├── .github ├── ISSUE_TEMPLATE │ ├── BUG_REPORT.md │ ├── FEATURE_REQUEST.md │ └── REFACTOR.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── cmake.yml │ └── doxygen.yml ├── .gitignore ├── .vscode ├── c_cpp_properties.json └── launch.json ├── CMakeLists.txt ├── ChangeLog.txt ├── LICENSE.md ├── README.md ├── docs ├── FRAMEWORK_STRUCTURE.md ├── PERFORMANCE_LIBRARY_INSTRUCTIONS.md ├── doxygen │ ├── CustomDoxygen.css │ ├── DoxygenLayout.xml │ ├── doxygen-awesome │ │ ├── LICENSE │ │ ├── doxygen-awesome-darkmode-toggle.js │ │ ├── doxygen-awesome-fragment-copy-button.js │ │ ├── doxygen-awesome-interactive-toc.js │ │ ├── doxygen-awesome-paragraph-link.js │ │ ├── doxygen-awesome-sidebar-only-darkmode-toggle.css │ │ ├── doxygen-awesome-sidebar-only.css │ │ ├── doxygen-awesome-tabs.js │ │ ├── doxygen-awesome.css │ │ ├── footer.html │ │ └── header.html │ ├── doxygen_config │ └── doxygen_postscript.sh └── framework.svg ├── examples ├── CMakeLists.txt ├── include │ ├── _common.h │ ├── ambi_bin.h │ ├── ambi_dec.h │ ├── ambi_drc.h │ ├── ambi_enc.h │ ├── ambi_roomsim.h │ ├── array2sh.h │ ├── beamformer.h │ ├── binauraliser.h │ ├── binauraliser_nf.h │ ├── decorrelator.h │ ├── dirass.h │ ├── matrixconv.h │ ├── multiconv.h │ ├── panner.h │ ├── pitch_shifter.h │ ├── powermap.h │ ├── rotator.h │ ├── sldoa.h │ ├── spreader.h │ └── tvconv.h └── src │ ├── ambi_bin │ ├── ambi_bin.c │ ├── ambi_bin_internal.c │ └── ambi_bin_internal.h │ ├── ambi_dec │ ├── ambi_dec.c │ ├── ambi_dec_internal.c │ └── ambi_dec_internal.h │ ├── ambi_drc │ ├── ambi_drc.c │ ├── ambi_drc_internal.c │ └── ambi_drc_internal.h │ ├── ambi_enc │ ├── ambi_enc.c │ ├── ambi_enc_internal.c │ └── ambi_enc_internal.h │ ├── ambi_roomsim │ ├── ambi_roomsim.c │ ├── ambi_roomsim_internal.c │ └── ambi_roomsim_internal.h │ ├── array2sh │ ├── array2sh.c │ ├── array2sh_internal.c │ └── array2sh_internal.h │ ├── beamformer │ ├── beamformer.c │ ├── beamformer_internal.c │ └── beamformer_internal.h │ ├── binauraliser │ ├── binauraliser.c │ ├── binauraliser_internal.c │ └── binauraliser_internal.h │ ├── binauraliser_nf │ ├── binauraliser_nf.c │ ├── binauraliser_nf_internal.c │ └── binauraliser_nf_internal.h │ ├── decorrelator │ ├── decorrelator.c │ ├── decorrelator_internal.c │ └── decorrelator_internal.h │ ├── dirass │ ├── dirass.c │ ├── dirass_internal.c │ └── dirass_internal.h │ ├── matrixconv │ ├── matrixconv.c │ ├── matrixconv_internal.c │ └── matrixconv_internal.h │ ├── multiconv │ ├── multiconv.c │ ├── multiconv_internal.c │ └── multiconv_internal.h │ ├── panner │ ├── panner.c │ ├── panner_internal.c │ └── panner_internal.h │ ├── pitch_shifter │ ├── pitch_shifter.c │ ├── pitch_shifter_internal.c │ └── pitch_shifter_internal.h │ ├── powermap │ ├── powermap.c │ ├── powermap_internal.c │ └── powermap_internal.h │ ├── rotator │ ├── rotator.c │ ├── rotator_internal.c │ └── rotator_internal.h │ ├── sldoa │ ├── sldoa.c │ ├── sldoa_internal.c │ └── sldoa_internal.h │ ├── spreader │ ├── spreader.c │ ├── spreader_internal.c │ └── spreader_internal.h │ └── tvconv │ ├── tvconv.c │ ├── tvconv_internal.c │ └── tvconv_internal.h ├── extras ├── CMakeLists.txt ├── matlab │ ├── SAF_MATLAB_CODE.md │ ├── saf_default_hrirs │ │ └── RUN_ME.m │ ├── saf_sofa_reader_module │ │ └── saf_sofa_open.m │ └── utils │ │ └── mat2c.m ├── safmex │ ├── BUILD_SAFMEX.m │ ├── CMakeLists.txt │ ├── CXX_API │ │ ├── CMakeLists.txt │ │ ├── TESTS.m │ │ ├── saf_afSTFT.cpp │ │ └── safmex.hpp │ ├── SAFMEX.md │ ├── safmex.h │ ├── safmex_afSTFT.c │ ├── safmex_afSTFT.m │ ├── safmex_faf_IIRFilterbank.c │ ├── safmex_faf_IIRFilterbank.m │ ├── safmex_generateVBAPgainTable3D.c │ ├── safmex_generateVBAPgainTable3D.m │ ├── safmex_getSHcomplex.c │ ├── safmex_getSHcomplex.m │ ├── safmex_getSHreal.c │ ├── safmex_getSHreal.m │ ├── safmex_latticeDecorrelator.c │ ├── safmex_latticeDecorrelator.m │ ├── safmex_qmf.c │ ├── safmex_qmf.m │ ├── safmex_tests │ │ ├── SAFMEX_TESTS.m │ │ └── safmex_tracker3d_tests.m │ ├── safmex_tracker3d.c │ └── safmex_tracker3d.m ├── safpy │ └── SAFPY.md └── safwwise │ └── SAFWWISE.md ├── framework ├── CMakeLists.txt ├── include │ ├── saf.h │ └── saf_externals.h ├── modules │ ├── CMakeLists.txt │ ├── saf_cdf4sap │ │ ├── saf_cdf4sap.c │ │ └── saf_cdf4sap.h │ ├── saf_hades │ │ ├── saf_hades.h │ │ ├── saf_hades_analysis.c │ │ ├── saf_hades_analysis.h │ │ ├── saf_hades_internal.c │ │ ├── saf_hades_internal.h │ │ ├── saf_hades_synthesis.c │ │ └── saf_hades_synthesis.h │ ├── saf_hoa │ │ ├── saf_hoa.c │ │ ├── saf_hoa.h │ │ ├── saf_hoa_internal.c │ │ └── saf_hoa_internal.h │ ├── saf_hrir │ │ ├── saf_default_hrirs.c │ │ ├── saf_hrir.c │ │ └── saf_hrir.h │ ├── saf_reverb │ │ ├── saf_reverb.c │ │ ├── saf_reverb.h │ │ ├── saf_reverb_internal.c │ │ └── saf_reverb_internal.h │ ├── saf_sh │ │ ├── saf_sh.c │ │ ├── saf_sh.h │ │ ├── saf_sh_internal.c │ │ └── saf_sh_internal.h │ ├── saf_sofa_reader │ │ ├── CMakeLists.txt │ │ ├── libmysofa │ │ │ ├── LICENSE │ │ │ ├── internal │ │ │ │ ├── hdf_dataobject.c │ │ │ │ ├── hdf_fractalhead.c │ │ │ │ ├── hdf_reader.c │ │ │ │ ├── hdf_reader.h │ │ │ │ ├── kdtree.c │ │ │ │ ├── kdtree.h │ │ │ │ ├── mysofa_internal.c │ │ │ │ └── mysofa_internal.h │ │ │ ├── mysofa.c │ │ │ └── mysofa.h │ │ ├── saf_sofa_reader.c │ │ └── saf_sofa_reader.h │ ├── saf_tracker │ │ ├── saf_tracker.c │ │ ├── saf_tracker.h │ │ ├── saf_tracker_internal.c │ │ └── saf_tracker_internal.h │ ├── saf_utilities │ │ ├── saf_utilities.h │ │ ├── saf_utility_bessel.c │ │ ├── saf_utility_bessel.h │ │ ├── saf_utility_complex.c │ │ ├── saf_utility_complex.h │ │ ├── saf_utility_decor.c │ │ ├── saf_utility_decor.h │ │ ├── saf_utility_dvf.c │ │ ├── saf_utility_dvf.h │ │ ├── saf_utility_fft.c │ │ ├── saf_utility_fft.h │ │ ├── saf_utility_filters.c │ │ ├── saf_utility_filters.h │ │ ├── saf_utility_geometry.c │ │ ├── saf_utility_geometry.h │ │ ├── saf_utility_latticeCoeffs.c │ │ ├── saf_utility_loudspeaker_presets.c │ │ ├── saf_utility_loudspeaker_presets.h │ │ ├── saf_utility_matrixConv.c │ │ ├── saf_utility_matrixConv.h │ │ ├── saf_utility_misc.c │ │ ├── saf_utility_misc.h │ │ ├── saf_utility_pitch.c │ │ ├── saf_utility_pitch.h │ │ ├── saf_utility_qmf.c │ │ ├── saf_utility_qmf.h │ │ ├── saf_utility_sensorarray_presets.c │ │ ├── saf_utility_sensorarray_presets.h │ │ ├── saf_utility_sort.c │ │ ├── saf_utility_sort.h │ │ ├── saf_utility_veclib.c │ │ └── saf_utility_veclib.h │ └── saf_vbap │ │ ├── saf_vbap.c │ │ ├── saf_vbap.h │ │ ├── saf_vbap_internal.c │ │ └── saf_vbap_internal.h └── resources │ ├── CMakeLists.txt │ ├── afSTFT │ ├── LICENSE.txt │ ├── afSTFT_internal.c │ ├── afSTFT_internal.h │ ├── afSTFT_protoFilter.h │ ├── afSTFTlib.c │ └── afSTFTlib.h │ ├── convhull_3d │ ├── LICENSE │ ├── convhull_3d.c │ └── convhull_3d.h │ ├── kissFFT │ ├── COPYING.txt │ ├── _kiss_fft_guts.h │ ├── kiss_fft.c │ ├── kiss_fft.h │ ├── kiss_fftr.c │ └── kiss_fftr.h │ ├── md_malloc │ ├── LICENSE │ ├── md_malloc.c │ └── md_malloc.h │ ├── speex_resampler │ ├── COPYING │ ├── arch.h │ ├── os_support.h │ ├── resample.c │ ├── resample_neon.h │ ├── resample_sse.h │ ├── speex_resampler.h │ └── speexdsp_types.h │ └── zlib │ ├── README │ ├── adler32.c │ ├── compress.c │ ├── crc32.c │ ├── crc32.h │ ├── deflate.c │ ├── deflate.h │ ├── infback.c │ ├── inffast.c │ ├── inffast.h │ ├── inffixed.h │ ├── inflate.c │ ├── inflate.h │ ├── inftrees.c │ ├── inftrees.h │ ├── trees.c │ ├── trees.h │ ├── uncompr.c │ ├── zconf.h │ ├── zlib.h │ ├── zutil.c │ └── zutil.h ├── saf.svg ├── scripts ├── install-safipp.bat ├── install-safipp.sh ├── install-safipp_oneAPI_2024.bat ├── install-safmkl.bat ├── install-safmkl.sh ├── install-safmkl_oneAPI_2024.bat ├── saf_ipp_list.txt └── saf_mkl_list └── test ├── CMakeLists.txt ├── include ├── saf_test.h ├── timer.h ├── unity.h └── unity_internals.h ├── saf_test_VS ├── saf_test.vcxproj ├── saf_test.vcxproj.filters ├── saf_test.vcxproj.user └── test.sln ├── src ├── resources │ ├── timer.c │ └── unity.c ├── saf_test.c ├── saf_test_wrapper.cpp ├── test__cdf4sap_module.c ├── test__examples.c ├── test__hades_module.c ├── test__hoa_module.c ├── test__hrir_module.c ├── test__resources.c ├── test__reverb_module.c ├── test__sh_module.c ├── test__sofa_reader_module.c ├── test__tracker_module.c ├── test__utilities_module.c └── test__vbap_module.c └── test.xcodeproj ├── project.pbxproj └── project.xcworkspace ├── contents.xcworkspacedata └── xcshareddata └── IDEWorkspaceChecks.plist /.github/ISSUE_TEMPLATE/BUG_REPORT.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Report a bug here, or email leo.mccormack(at)aalto.fi 4 | labels: bug 5 | --- 6 | 7 | Please replace every line in curly brackets { like this } with appropriate answers, and remove this line. 8 | 9 | ## Description 10 | 11 | { Please provide a clear and concise description of the bug. } 12 | 13 | ## Environment 14 | 15 | 1. OS: { e.g. MacOSX 10.?, Windows 10, MSYS2, Ubuntu 20.04, etc. } 16 | 2. Compiler: { e.g. Clang, GCC, MSVC, etc. } 17 | 3. SAF performance library being used: { e.g. SAF_USE_INTEL_MKL, SAF_USE_APPLE_ACCELERATE, etc. } 18 | 4. Any optional SAF flags enabled: { e.g. SAF_USE_TRACKER_MODULE, SAF_USE_INTEL_IPP, etc. } 19 | 5. Other environment details: { e.g. IDE, CMake, etc. } 20 | 21 | ## Reproducible Steps 22 | 23 | Steps to create the smallest reproducible scenario: 24 | 1. { e.g. Build SAF with above environment... } 25 | 2. { e.g. Call saf_function() with the following input arguments: [ ]... } 26 | 3. { e.g. Perhaps doing something with output... } 27 | 4. { e.g. Error appears (hard crash), or behaviour is unexpected... } 28 | 29 | ## Expected Output 30 | 31 | { Please describe what you expected to happen. } 32 | 33 | ## Actual Output 34 | 35 | { Please describe what actually happened. } 36 | 37 | ## Additional information 38 | 39 | { Any additional information, including logs or screenshots if you have any. } 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Request a feature here, or email leo.mccormack(at)aalto.fi 4 | labels: feature 5 | --- 6 | 7 | Please replace every line in curly brackets { like this } with appropriate answers, and remove this line. 8 | 9 | ## Problem to Solve 10 | 11 | { Please describe the problem you would like to solve. } 12 | 13 | ## Current Workaround 14 | 15 | { Please describe how you currently solve or work around this problem, given SAF's limitation. } 16 | 17 | ## Proposed Solution 18 | 19 | { Please describe the solution you would like SAF to provide, to solve the problem above. } 20 | 21 | ## Additional Information 22 | 23 | { Any additional information, including logs or screenshots if you have any. } 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/REFACTOR.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Refactor 3 | about: Propose an architecture refactor here, or email leo.mccormack(at)aalto.fi 4 | labels: refactor 5 | --- 6 | 7 | Please replace every line in curly brackets { like this } with appropriate answers, and remove this line. 8 | 9 | ## Problem to Solve 10 | 11 | { Please describe the problem with the current architecture that you would like to solve. } 12 | 13 | ## Proposed Solution 14 | 15 | { Please describe how you would like to change the architecture, to solve the problem above. } 16 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Please replace every line in curly brackets ( { like this } ) with an appropriate description, and remove this line. 2 | 3 | ## What is the goal of this PR? 4 | 5 | { Please describe the goal of this PR, why they are valuable to achieve, and reference the related GitHub issues. } 6 | 7 | ## What are the changes implemented in this PR? 8 | 9 | { Please explain what you implemented, why your changes are the best way to achieve the goal(s) above, and reference the GitHub issues to be automatically closed, such like 'closes #number'. } 10 | -------------------------------------------------------------------------------- /.github/workflows/cmake.yml: -------------------------------------------------------------------------------- 1 | name: CMake Build 2 | 3 | on: 4 | push: 5 | branches: [ master, develop ] 6 | 7 | env: 8 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 9 | BUILD_TYPE: Release 10 | 11 | jobs: 12 | build: 13 | # The CMake configure and build commands are platform agnostic and should work equally 14 | # well on Windows or Mac. You can convert this to a matrix build if you need 15 | # cross-platform coverage. 16 | # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 17 | # runs-on: ubuntu-latest 18 | runs-on: ${{ matrix.os }} 19 | strategy: 20 | matrix: 21 | os: [ubuntu-latest, macOS-latest, windows-latest] 22 | 23 | steps: 24 | - uses: actions/checkout@v2 25 | 26 | - name: Fetch SAF dependencies 27 | if: ${{ contains( runner.os, 'Linux' ) }} 28 | run: | 29 | sudo apt-get update && sudo apt-get install libhdf5-dev libnetcdf-dev libnetcdff-dev liblapack3 liblapack-dev libopenblas-dev liblapacke-dev 30 | - name: Fetch OpenBLAS (Windows) 31 | if: ${{ contains( runner.os, 'Windows' ) }} 32 | run: | 33 | curl https://github.com/OpenMathLib/OpenBLAS/releases/download/v0.3.26/OpenBLAS-0.3.26-x64.zip -L -o tmp.zip 34 | 7z x ./tmp.zip -oOpenBLAS 35 | cp ./OpenBLAS/lib/libopenblas.lib $GITHUB_WORKSPACE 36 | cp ./OpenBLAS/bin/libopenblas.dll $GITHUB_WORKSPACE 37 | echo "$GITHUB_WORKSPACE" >> $GITHUB_PATH 38 | - name: Create Build Environment 39 | # Some projects don't allow in-source building, so create a separate build directory 40 | # We'll use this as our working directory for all subsequent commands 41 | run: cmake -E make_directory ${{runner.workspace}}/build 42 | 43 | - name: Configure CMake (Linux) 44 | # Use a bash shell so we can use the same syntax for environment variable 45 | # access regardless of the host operating system 46 | shell: bash 47 | working-directory: ${{runner.workspace}}/build 48 | if: ${{ contains( runner.os, 'Linux' ) }} 49 | run: | 50 | cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSAF_PERFORMANCE_LIB=SAF_USE_OPEN_BLAS_AND_LAPACKE -DSAF_ENABLE_TRACKER_MODULE=1 -DSAF_ENABLE_SOFA_READER_MODULE=1 -DSAF_ENABLE_HADES_MODULE=1 51 | 52 | - name: Configure CMake (macOS) 53 | shell: bash 54 | working-directory: ${{runner.workspace}}/build 55 | if: ${{ contains( runner.os, 'macOS' ) }} 56 | run: | 57 | cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSAF_PERFORMANCE_LIB=SAF_USE_APPLE_ACCELERATE -DSAF_ENABLE_TRACKER_MODULE=1 -DSAF_ENABLE_SOFA_READER_MODULE=1 -DSAF_ENABLE_HADES_MODULE=1 58 | 59 | - name: Configure CMake (Windows) 60 | shell: bash 61 | working-directory: ${{runner.workspace}}/build 62 | if: ${{ contains( runner.os, 'Windows' ) }} 63 | run: | 64 | cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSAF_PERFORMANCE_LIB=SAF_USE_OPEN_BLAS_AND_LAPACKE -DOPENBLAS_LIBRARY=$GITHUB_WORKSPACE/OpenBLAS/lib/libopenblas.lib -DLAPACKE_LIBRARY=$GITHUB_WORKSPACE/OpenBLAS/lib/libopenblas.lib -DOPENBLAS_HEADER_PATH=$GITHUB_WORKSPACE/OpenBLAS/include/ -DSAF_ENABLE_TRACKER_MODULE=1 -DSAF_ENABLE_SOFA_READER_MODULE=1 -DSAF_ENABLE_HADES_MODULE=1 65 | 66 | - name: Build 67 | working-directory: ${{runner.workspace}}/build 68 | shell: bash 69 | # Execute the build. You can specify a specific target with "--target " 70 | run: cmake --build . --config $BUILD_TYPE 71 | 72 | - name: Test (Unix) 73 | if: ${{ contains( runner.os, 'Linux' ) || contains( runner.os, 'macOS' )}} 74 | working-directory: ${{runner.workspace}}/build 75 | shell: bash 76 | # Execute tests 77 | run: ./test/saf_test 78 | 79 | - name: Test (Windows) 80 | if: ${{ contains( runner.os, 'Windows' ) }} 81 | working-directory: ${{runner.workspace}}/build 82 | shell: bash 83 | run: | 84 | cp $GITHUB_WORKSPACE/libopenblas.dll ./test/$BUILD_TYPE/ 85 | ls -lh ./test/$BUILD_TYPE/ 86 | ./test/$BUILD_TYPE/saf_test.exe 87 | -------------------------------------------------------------------------------- /.github/workflows/doxygen.yml: -------------------------------------------------------------------------------- 1 | name: Doxygen Generate 2 | 3 | # Controls when the action will run. Triggers the workflow on push or pull request 4 | # events but only for the master branch 5 | on: 6 | push: 7 | branches: [ master ] 8 | 9 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 10 | jobs: 11 | # This workflow contains a single job called "build" 12 | build: 13 | # The type of runner that the job will run on 14 | runs-on: ubuntu-latest 15 | 16 | # Steps represent a sequence of tasks that will be executed as part of the job 17 | steps: 18 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 19 | - uses: actions/checkout@v2 20 | 21 | - name: Doxygen Action 22 | uses: mattnotmitt/doxygen-action@v1.1.0 23 | with: 24 | # Path to Doxyfile 25 | doxyfile-path: "./doxygen_config" 26 | # Working directory 27 | working-directory: "./docs/doxygen/" 28 | 29 | - name: Post Script 30 | # Run post-script 31 | shell: bash 32 | working-directory: "./docs/doxygen/" 33 | run: ./doxygen_postscript.sh 34 | 35 | - name: Deploy 36 | uses: peaceiris/actions-gh-pages@v3 37 | with: 38 | github_token: ${{ secrets.GITHUB_TOKEN }} 39 | # Doxyfile build documentation to html directory. 40 | publish_dir: ./docs/doxygen/html 41 | 42 | 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | deprecated/ 2 | docs/doxygen/html 3 | docs/doxygen/latex 4 | xcuserdata/ 5 | xcshareddata/ 6 | build/ 7 | x64/ 8 | UpgradeLog.htm 9 | .vs/ 10 | *.DS_Store 11 | *idea/ 12 | cmake-build-debug/ 13 | cmake-build-release/ 14 | *.db 15 | dependencies/ 16 | *.c~ 17 | *.m~ 18 | *.h~ 19 | *.cpp~ 20 | *.hpp~ 21 | *.zip 22 | *.mexmaci64 23 | *.mexa64 24 | *.mexw64 25 | *.bak 26 | saf_doxygen.tag 27 | build_saf_ipp_custom_intel64.sh 28 | libfftw3.a 29 | libfftw3f.a 30 | fftw3.h 31 | build_saf_ipp_custom_intel64.bat 32 | export.def 33 | main.c 34 | main.obj 35 | saf_ipp_custom.dll 36 | saf_ipp_custom.exp 37 | saf_ipp_custom.lib 38 | VTune Profiler Results/ -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "commonIncludePaths": [ 4 | "${workspaceFolder}/**", 5 | "${workspaceFolder}/framework/include", 6 | "${workspaceFolder}/examples/include", 7 | "${workspaceFolder}/test/unity", 8 | "${workspaceFolder}/test/timer" 9 | ], 10 | "commonDefs": [ 11 | "SAF_USE_INTEL_MKL", 12 | "SAF_USE_INTEL_IPP", 13 | "SAF_ENABLE_SOFA_READER_MODULE", 14 | "SAF_ENABLE_TRACKER_MODULE" 15 | ] 16 | }, 17 | "configurations": [ 18 | { 19 | "name": "Mac", 20 | "includePath": [ 21 | "${commonIncludePaths}", 22 | "${workspaceFolder}/dependencies/MacOSX/include", 23 | "/opt/intel/oneapi/mkl/latest/include", 24 | "/opt/intel/oneapi/ipp/latest/include" 25 | ], 26 | "defines": [ 27 | "${commonDefs}" 28 | ], 29 | "macFrameworkPath": [], 30 | "compilerPath": "/usr/bin/clang", 31 | "cStandard": "c11", 32 | "cppStandard": "c++17", 33 | "intelliSenseMode": "${default}", 34 | "compileCommands": "${workspaceFolder}/build/compile_commands.json", 35 | "configurationProvider": "ms-vscode.cmake-tools" 36 | }, 37 | { 38 | "name": "Win64", 39 | "includePath": [ 40 | "${commonIncludePaths}", 41 | "${workspaceFolder}/dependencies/Win64/include", 42 | "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/include" 43 | ], 44 | "defines": [ 45 | "${commonDefs}" 46 | ], 47 | "configurationProvider": "ms-vscode.cmake-tools" 48 | }, 49 | { 50 | "name": "Linux-arm", 51 | "includePath": [ 52 | "${commonIncludePaths}" 53 | ], 54 | "defines": [ 55 | "SAF_USE_OPEN_BLAS_AND_LAPACKE", 56 | "SAF_ENABLE_SOFA_READER_MODULE", 57 | "SAF_ENABLE_TRACKER_MODULE" 58 | ], 59 | "macFrameworkPath": [], 60 | "compilerPath": "/usr/bin/gcc", 61 | "cStandard": "c11", 62 | "cppStandard": "c++17", 63 | "intelliSenseMode": "${default}", 64 | "configurationProvider": "ms-vscode.cmake-tools" 65 | } 66 | ], 67 | "version": 4 68 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | 8 | { 9 | "name": "(gdb) Launch", 10 | "type": "cppdbg", 11 | "request": "launch", 12 | "program": "${workspaceFolder}/build/test/saf_test", 13 | "args": [], 14 | "stopAtEntry": false, 15 | "cwd": "${fileDirname}", 16 | "environment": [], 17 | "externalConsole": false, 18 | "MIMode": "gdb", 19 | "setupCommands": [ 20 | { 21 | "description": "Enable pretty-printing for gdb", 22 | "text": "-enable-pretty-printing", 23 | "ignoreFailures": true 24 | } 25 | ] 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.15) 3 | 4 | project(saf_head) 5 | 6 | # Project options/defaults 7 | option(BUILD_SHARED_LIBS "Build shared instead of static libraries." OFF) 8 | option(SAF_BUILD_TESTS "Build SAF unit tests." ON) 9 | option(SAF_BUILD_EXAMPLES "Build SAF examples." ON) 10 | option(SAF_BUILD_EXTRAS "Build SAF extras." OFF) 11 | option(SAF_ENABLE_SOFA_READER_MODULE "Enable the SAF SOFA READER module" OFF) 12 | option(SAF_ENABLE_TRACKER_MODULE "Enable the SAF TRACKER module" OFF) 13 | option(SAF_ENABLE_HADES_MODULE "Enable the SAF HADES module" OFF) 14 | option(SAF_USE_INTEL_IPP "Use Intel IPP for the FFT, resampler, etc." OFF) 15 | option(SAF_USE_FFTW "Use FFTW3 for the FFT." OFF) 16 | option(SAF_ENABLE_SIMD "Enable the use of SSE3, AVX2, AVX512" OFF) 17 | option(SAF_ENABLE_NETCDF "Enable netcdf for the sofa reader module" OFF) 18 | option(SAF_USE_FAST_MATH_FLAG "Enable -ffast-math compiler flag" ON) 19 | if(NOT DEFINED SAF_PERFORMANCE_LIB AND NOT APPLE) 20 | message(FATAL_ERROR "You must define the SAF_PERFORMANCE_LIB environment variable") 21 | endif() 22 | if(NOT DEFINED SAF_PERFORMANCE_LIB AND APPLE) 23 | set(SAF_PERFORMANCE_LIB "SAF_USE_APPLE_ACCELERATE") 24 | endif() 25 | #message(STATUS "PERFORMANCE LIB is ${SAF_PERFORMANCE_LIB}") 26 | if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") 27 | set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) 28 | endif() 29 | 30 | # Configure CMake 31 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 32 | set(CMAKE_C_STANDARD 99) 33 | set(CMAKE_C_STANDARD_REQUIRED OFF) 34 | set(CMAKE_CXX_STANDARD 14) 35 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 36 | set(CMAKE_CXX_EXTENSIONS OFF) 37 | set(CMAKE_EXPORT_COMPILE_COMMANDS true) 38 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 39 | 40 | # Platform specific flags and definitions 41 | if(MSVC) 42 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") 43 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") 44 | elseif(APPLE) 45 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++") 46 | set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64") 47 | set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0") 48 | elseif(UNIX AND NOT APPLE AND NOT ANDROID) 49 | add_definitions( 50 | #-std=c++11 51 | -DLINUX=1 52 | ) 53 | endif() 54 | 55 | # add subdirectory for SAF 56 | add_subdirectory(framework) 57 | 58 | # Optionally, also add the SAF examples and/or unit testing program 59 | set(example_prefix "saf_example_") 60 | if(SAF_BUILD_EXAMPLES) 61 | add_subdirectory(examples) 62 | endif() 63 | if(SAF_BUILD_EXTRAS) 64 | add_subdirectory(extras) 65 | endif() 66 | if(SAF_BUILD_TESTS) 67 | add_subdirectory(test) 68 | endif() 69 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # Spatial_Audio_Framework License 2 | 3 | This software is dual-licensed. 4 | 5 | [ISC License](https://choosealicense.com/licenses/isc/): 6 | * By default, this software is governed permissively under the terms of the ISC license; since all of the core (non-optional) modules are licensed as such. Also note that all third-party code, which has been adapted or adopted by these core modules, is also provided under similar permissive licensing terms ([MIT](https://choosealicense.com/licenses/mit/), [BSD](https://choosealicense.com/licenses/bsd-2-clause/), [WOL](https://dspguru.com/wide-open-license/), etc.). The specific license employed by each third-party code is stated clearly in the code comments at the point of its inclusion. 7 | 8 | [GNU GPLv2 License](https://choosealicense.com/licenses/gpl-2.0/): 9 | * Including and enabling certain optional modules, which are instead provided under the copy-left GNU GPLv2 license, will mean that the use of this software is instead governed by the GNU GPLv2 licencing terms. 10 | 11 | Note that the license employed by each module is stated clearly in [saf.h](framework/include/saf.h). For more information, refer to the license terms found at the top of each source and header file. 12 | -------------------------------------------------------------------------------- /docs/doxygen/doxygen-awesome/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 jothepro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/doxygen/doxygen-awesome/doxygen-awesome-fragment-copy-button.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Doxygen Awesome 4 | https://github.com/jothepro/doxygen-awesome-css 5 | 6 | MIT License 7 | 8 | Copyright (c) 2022 - 2023 jothepro 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | */ 29 | 30 | class DoxygenAwesomeFragmentCopyButton extends HTMLElement { 31 | constructor() { 32 | super(); 33 | this.onclick=this.copyContent 34 | } 35 | static title = "Copy to clipboard" 36 | static copyIcon = `` 37 | static successIcon = `` 38 | static successDuration = 980 39 | static init() { 40 | $(function() { 41 | $(document).ready(function() { 42 | if(navigator.clipboard) { 43 | const fragments = document.getElementsByClassName("fragment") 44 | for(const fragment of fragments) { 45 | const fragmentWrapper = document.createElement("div") 46 | fragmentWrapper.className = "doxygen-awesome-fragment-wrapper" 47 | const fragmentCopyButton = document.createElement("doxygen-awesome-fragment-copy-button") 48 | fragmentCopyButton.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon 49 | fragmentCopyButton.title = DoxygenAwesomeFragmentCopyButton.title 50 | 51 | fragment.parentNode.replaceChild(fragmentWrapper, fragment) 52 | fragmentWrapper.appendChild(fragment) 53 | fragmentWrapper.appendChild(fragmentCopyButton) 54 | 55 | } 56 | } 57 | }) 58 | }) 59 | } 60 | 61 | 62 | copyContent() { 63 | const content = this.previousSibling.cloneNode(true) 64 | // filter out line number from file listings 65 | content.querySelectorAll(".lineno, .ttc").forEach((node) => { 66 | node.remove() 67 | }) 68 | let textContent = content.textContent 69 | // remove trailing newlines that appear in file listings 70 | let numberOfTrailingNewlines = 0 71 | while(textContent.charAt(textContent.length - (numberOfTrailingNewlines + 1)) == '\n') { 72 | numberOfTrailingNewlines++; 73 | } 74 | textContent = textContent.substring(0, textContent.length - numberOfTrailingNewlines) 75 | navigator.clipboard.writeText(textContent); 76 | this.classList.add("success") 77 | this.innerHTML = DoxygenAwesomeFragmentCopyButton.successIcon 78 | window.setTimeout(() => { 79 | this.classList.remove("success") 80 | this.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon 81 | }, DoxygenAwesomeFragmentCopyButton.successDuration); 82 | } 83 | } 84 | 85 | customElements.define("doxygen-awesome-fragment-copy-button", DoxygenAwesomeFragmentCopyButton) 86 | -------------------------------------------------------------------------------- /docs/doxygen/doxygen-awesome/doxygen-awesome-interactive-toc.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Doxygen Awesome 4 | https://github.com/jothepro/doxygen-awesome-css 5 | 6 | MIT License 7 | 8 | Copyright (c) 2022 - 2023 jothepro 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | */ 29 | 30 | class DoxygenAwesomeInteractiveToc { 31 | static topOffset = 38 32 | static hideMobileMenu = true 33 | static headers = [] 34 | 35 | static init() { 36 | window.addEventListener("load", () => { 37 | let toc = document.querySelector(".contents > .toc") 38 | if(toc) { 39 | toc.classList.add("interactive") 40 | if(!DoxygenAwesomeInteractiveToc.hideMobileMenu) { 41 | toc.classList.add("open") 42 | } 43 | document.querySelector(".contents > .toc > h3")?.addEventListener("click", () => { 44 | if(toc.classList.contains("open")) { 45 | toc.classList.remove("open") 46 | } else { 47 | toc.classList.add("open") 48 | } 49 | }) 50 | 51 | document.querySelectorAll(".contents > .toc > ul a").forEach((node) => { 52 | let id = node.getAttribute("href").substring(1) 53 | DoxygenAwesomeInteractiveToc.headers.push({ 54 | node: node, 55 | headerNode: document.getElementById(id) 56 | }) 57 | 58 | document.getElementById("doc-content")?.addEventListener("scroll",this.throttle(DoxygenAwesomeInteractiveToc.update, 100)) 59 | }) 60 | DoxygenAwesomeInteractiveToc.update() 61 | } 62 | }) 63 | } 64 | 65 | static update() { 66 | let active = DoxygenAwesomeInteractiveToc.headers[0]?.node 67 | DoxygenAwesomeInteractiveToc.headers.forEach((header) => { 68 | let position = header.headerNode.getBoundingClientRect().top 69 | header.node.classList.remove("active") 70 | header.node.classList.remove("aboveActive") 71 | if(position < DoxygenAwesomeInteractiveToc.topOffset) { 72 | active = header.node 73 | active?.classList.add("aboveActive") 74 | } 75 | }) 76 | active?.classList.add("active") 77 | active?.classList.remove("aboveActive") 78 | } 79 | 80 | static throttle(func, delay) { 81 | let lastCall = 0; 82 | return function (...args) { 83 | const now = new Date().getTime(); 84 | if (now - lastCall < delay) { 85 | return; 86 | } 87 | lastCall = now; 88 | return setTimeout(() => {func(...args)}, delay); 89 | }; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /docs/doxygen/doxygen-awesome/doxygen-awesome-paragraph-link.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Doxygen Awesome 4 | https://github.com/jothepro/doxygen-awesome-css 5 | 6 | MIT License 7 | 8 | Copyright (c) 2022 - 2023 jothepro 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | */ 29 | 30 | class DoxygenAwesomeParagraphLink { 31 | // Icon from https://fonts.google.com/icons 32 | // Licensed under the Apache 2.0 license: 33 | // https://www.apache.org/licenses/LICENSE-2.0.html 34 | static icon = `` 35 | static title = "Permanent Link" 36 | static init() { 37 | $(function() { 38 | $(document).ready(function() { 39 | document.querySelectorAll(".contents a.anchor[id], .contents .groupheader > a[id]").forEach((node) => { 40 | let anchorlink = document.createElement("a") 41 | anchorlink.setAttribute("href", `#${node.getAttribute("id")}`) 42 | anchorlink.setAttribute("title", DoxygenAwesomeParagraphLink.title) 43 | anchorlink.classList.add("anchorlink") 44 | node.classList.add("anchor") 45 | anchorlink.innerHTML = DoxygenAwesomeParagraphLink.icon 46 | node.parentElement.appendChild(anchorlink) 47 | }) 48 | }) 49 | }) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /docs/doxygen/doxygen-awesome/doxygen-awesome-sidebar-only-darkmode-toggle.css: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | Doxygen Awesome 5 | https://github.com/jothepro/doxygen-awesome-css 6 | 7 | MIT License 8 | 9 | Copyright (c) 2021 - 2023 jothepro 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in all 19 | copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | SOFTWARE. 28 | 29 | */ 30 | 31 | @media screen and (min-width: 768px) { 32 | 33 | #MSearchBox { 34 | width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - var(--searchbar-height) - 1px); 35 | } 36 | 37 | #MSearchField { 38 | width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - 66px - var(--searchbar-height)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /docs/doxygen/doxygen-awesome/doxygen-awesome-sidebar-only.css: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Doxygen Awesome 4 | https://github.com/jothepro/doxygen-awesome-css 5 | 6 | MIT License 7 | 8 | Copyright (c) 2021 - 2023 jothepro 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | */ 29 | 30 | html { 31 | /* side nav width. MUST be = `TREEVIEW_WIDTH`. 32 | * Make sure it is wide enough to contain the page title (logo + title + version) 33 | */ 34 | --side-nav-fixed-width: 335px; 35 | --menu-display: none; 36 | 37 | --top-height: 120px; 38 | --toc-sticky-top: -25px; 39 | --toc-max-height: calc(100vh - 2 * var(--spacing-medium) - 25px); 40 | } 41 | 42 | #projectname { 43 | white-space: nowrap; 44 | } 45 | 46 | 47 | @media screen and (min-width: 768px) { 48 | html { 49 | --searchbar-background: var(--page-background-color); 50 | } 51 | 52 | #side-nav { 53 | min-width: var(--side-nav-fixed-width); 54 | max-width: var(--side-nav-fixed-width); 55 | top: var(--top-height); 56 | overflow: visible; 57 | } 58 | 59 | #nav-tree, #side-nav { 60 | height: calc(100vh - var(--top-height)) !important; 61 | } 62 | 63 | #nav-tree { 64 | padding: 0; 65 | } 66 | 67 | #top { 68 | display: block; 69 | border-bottom: none; 70 | height: var(--top-height); 71 | margin-bottom: calc(0px - var(--top-height)); 72 | max-width: var(--side-nav-fixed-width); 73 | overflow: hidden; 74 | background: var(--side-nav-background); 75 | } 76 | #main-nav { 77 | float: left; 78 | padding-right: 0; 79 | } 80 | 81 | .ui-resizable-handle { 82 | cursor: default; 83 | width: 1px !important; 84 | background: var(--separator-color); 85 | box-shadow: 0 calc(-2 * var(--top-height)) 0 0 var(--separator-color); 86 | } 87 | 88 | #nav-path { 89 | position: fixed; 90 | right: 0; 91 | left: var(--side-nav-fixed-width); 92 | bottom: 0; 93 | width: auto; 94 | } 95 | 96 | #doc-content { 97 | height: calc(100vh - 31px) !important; 98 | padding-bottom: calc(3 * var(--spacing-large)); 99 | padding-top: calc(var(--top-height) - 80px); 100 | box-sizing: border-box; 101 | margin-left: var(--side-nav-fixed-width) !important; 102 | } 103 | 104 | #MSearchBox { 105 | width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium))); 106 | } 107 | 108 | #MSearchField { 109 | width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - 65px); 110 | } 111 | 112 | #MSearchResultsWindow { 113 | left: var(--spacing-medium) !important; 114 | right: auto; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /docs/doxygen/doxygen-awesome/doxygen-awesome-tabs.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Doxygen Awesome 4 | https://github.com/jothepro/doxygen-awesome-css 5 | 6 | MIT License 7 | 8 | Copyright (c) 2023 jothepro 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | */ 29 | 30 | class DoxygenAwesomeTabs { 31 | 32 | static init() { 33 | window.addEventListener("load", () => { 34 | document.querySelectorAll(".tabbed:not(:empty)").forEach((tabbed, tabbedIndex) => { 35 | let tabLinkList = [] 36 | tabbed.querySelectorAll(":scope > ul > li").forEach((tab, tabIndex) => { 37 | tab.id = "tab_" + tabbedIndex + "_" + tabIndex 38 | let header = tab.querySelector(".tab-title") 39 | let tabLink = document.createElement("button") 40 | tabLink.classList.add("tab-button") 41 | tabLink.appendChild(header) 42 | header.title = header.textContent 43 | tabLink.addEventListener("click", () => { 44 | tabbed.querySelectorAll(":scope > ul > li").forEach((tab) => { 45 | tab.classList.remove("selected") 46 | }) 47 | tabLinkList.forEach((tabLink) => { 48 | tabLink.classList.remove("active") 49 | }) 50 | tab.classList.add("selected") 51 | tabLink.classList.add("active") 52 | }) 53 | tabLinkList.push(tabLink) 54 | if(tabIndex == 0) { 55 | tab.classList.add("selected") 56 | tabLink.classList.add("active") 57 | } 58 | }) 59 | let tabsOverview = document.createElement("div") 60 | tabsOverview.classList.add("tabs-overview") 61 | let tabsOverviewContainer = document.createElement("div") 62 | tabsOverviewContainer.classList.add("tabs-overview-container") 63 | tabLinkList.forEach((tabLink) => { 64 | tabsOverview.appendChild(tabLink) 65 | }) 66 | tabsOverviewContainer.appendChild(tabsOverview) 67 | tabbed.before(tabsOverviewContainer) 68 | 69 | function resize() { 70 | let maxTabHeight = 0 71 | tabbed.querySelectorAll(":scope > ul > li").forEach((tab, tabIndex) => { 72 | let visibility = tab.style.display 73 | tab.style.display = "block" 74 | maxTabHeight = Math.max(tab.offsetHeight, maxTabHeight) 75 | tab.style.display = visibility 76 | }) 77 | tabbed.style.height = `${maxTabHeight + 10}px` 78 | } 79 | 80 | resize() 81 | new ResizeObserver(resize).observe(tabbed) 82 | }) 83 | }) 84 | 85 | } 86 | 87 | static resize(tabbed) { 88 | 89 | } 90 | } -------------------------------------------------------------------------------- /docs/doxygen/doxygen-awesome/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 15 | 16 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/doxygen/doxygen-awesome/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | $projectname: $title 11 | $title 12 | 13 | 14 | 15 | $treeview 16 | $search 17 | $mathjax 18 | 19 | $extrastylesheet 20 | 21 | 22 | 23 | 30 | 31 | 32 |
33 | 34 | 35 |
36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
44 |
$projectname 45 |  $projectnumber 46 |
47 |
$projectbrief
48 |
53 |
$projectbrief
54 |
$searchbox
65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /docs/doxygen/doxygen_postscript.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | #A script to do some extra configurations that are not yet supported natively by doxygen 5 | 6 | echo "Running doxygen post-script" 7 | 8 | # Make the default detail level=4 for the "files" tab 9 | sudo chmod +rwx html 10 | sudo sed -i.bak 's/(document).ready(function() { init_search(); });/(document).ready(function() { init_search(); toggleLevel(4); });/' html/files.html && sudo rm html/files.html.bak 11 | 12 | #sed -i '' 's+(document).ready(function() { init_search(); });+(document).ready(function() { init_search(); toggleLevel(4); });+' html/files.html 13 | 14 | echo "Done!" 15 | 16 | set +e 17 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | message(STATUS "Configuring SAF examples:") 3 | 4 | if(NOT DEFINED saf_example_list) 5 | # List of examples which have the common structure (.h/.c, _internal.h/.c): 6 | set(saf_example_list 7 | ambi_bin 8 | ambi_dec 9 | ambi_drc 10 | ambi_enc 11 | ambi_roomsim 12 | array2sh 13 | beamformer 14 | binauraliser 15 | binauraliser_nf 16 | decorrelator 17 | dirass 18 | matrixconv 19 | multiconv 20 | panner 21 | pitch_shifter 22 | powermap 23 | rotator 24 | sldoa 25 | spreader 26 | tvconv) 27 | endif() 28 | 29 | # Find number of examples 30 | list(LENGTH saf_example_list num_examples) 31 | math(EXPR num_examples "${num_examples} - 1") 32 | 33 | # Loop over all examples 34 | foreach(current_example RANGE ${num_examples}) 35 | # Get current example string 36 | list(GET saf_example_list ${current_example} current_string) 37 | 38 | # Set-up project 39 | message(STATUS " ${current_string}") 40 | project("${example_prefix}${current_string}" LANGUAGES C) 41 | add_library(${PROJECT_NAME} STATIC) 42 | 43 | # Link with SAF 44 | target_link_libraries(${PROJECT_NAME} PRIVATE saf) 45 | 46 | # Source files 47 | target_sources(${PROJECT_NAME} 48 | PRIVATE 49 | ${CMAKE_CURRENT_SOURCE_DIR}/src/${current_string}/${current_string}_internal.c 50 | ${CMAKE_CURRENT_SOURCE_DIR}/src/${current_string}/${current_string}_internal.h 51 | ${CMAKE_CURRENT_SOURCE_DIR}/src/${current_string}/${current_string}.c 52 | ) 53 | 54 | # Extra source files specific to binauraliserNF 55 | if (current_string STREQUAL binauraliser_nf) 56 | target_sources(${PROJECT_NAME} 57 | PRIVATE 58 | ${CMAKE_CURRENT_SOURCE_DIR}/src/binauraliser/binauraliser_internal.h 59 | ${CMAKE_CURRENT_SOURCE_DIR}/src/binauraliser/binauraliser_internal.c 60 | ${CMAKE_CURRENT_SOURCE_DIR}/src/binauraliser/binauraliser.c 61 | ) 62 | endif() 63 | 64 | # enable compiler warnings 65 | if(UNIX) 66 | target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra) 67 | endif() 68 | 69 | # Include directory 70 | target_include_directories(${PROJECT_NAME} 71 | PUBLIC 72 | $ 73 | $ 74 | ) 75 | endforeach() 76 | -------------------------------------------------------------------------------- /examples/src/ambi_bin/ambi_bin_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file ambi_bin_internal.c 19 | * @brief A binaural Ambisonic decoder for reproducing Ambisonic sound scenes 20 | * over headphones 21 | * 22 | * The decoder offers choice over many different binaural decoding options [1-4] 23 | * It also supports sound-field rotation for head-tracking and can accomodate 24 | * loading custom HRIR sets via the SOFA standard. 25 | * 26 | * @test test__saf_example_ambi_bin() 27 | * 28 | * @see [1] Z. Ben-Hur, F. Brinkmann, J. Sheaffer, S. Weinzierl, and B. Rafaely, 29 | * "Spectral equalization in binaural signals represented by order- 30 | * truncated spherical harmonics" The Journal of the Acoustical 31 | * Society of America, vol. 141, no. 6, pp. 4087--4096, 2017. 32 | * @see [2] B. Bernschutz, A. V. Giner, C. Po"rschmann, and J. Arend, "Binaural 33 | * reproduction of plane waves with reduced modal order" Acta Acustica 34 | * united with Acustica, vol. 100, no. 5, pp. 972--983, 2014. 35 | * @see [3] Zaunschirm M, Scho"rkhuber C, Ho"ldrich R. Binaural rendering of 36 | * Ambisonic signals by head-related impulse response time alignment 37 | * and a diffuseness constraint. The Journal of the Acoustical Society 38 | * of America. 2018 Jun 19;143(6):3616-27 39 | * @see [4] Scho"rkhuber C, Zaunschirm M, Ho"ldrich R. Binaural Rendering of 40 | * Ambisonic Signals via Magnitude Least Squares. InProceedings of the 41 | * DAGA 2018 (Vol. 44, pp. 339-342). 42 | * 43 | * @author Leo McCormack 44 | * @date 14.04.2018 45 | * @license ISC 46 | */ 47 | 48 | #include "ambi_bin.h" 49 | #include "ambi_bin_internal.h" 50 | 51 | void ambi_bin_setCodecStatus(void* const hAmbi, CODEC_STATUS newStatus) 52 | { 53 | ambi_bin_data *pData = (ambi_bin_data*)(hAmbi); 54 | if(newStatus==CODEC_STATUS_NOT_INITIALISED){ 55 | /* Pause until current initialisation is complete */ 56 | while(pData->codecStatus == CODEC_STATUS_INITIALISING) 57 | SAF_SLEEP(10); 58 | } 59 | pData->codecStatus = newStatus; 60 | } 61 | -------------------------------------------------------------------------------- /examples/src/ambi_roomsim/ambi_roomsim_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file ambi_roomsim_internal.c 19 | * @brief A simple shoebox room Ambisonic encoder. 20 | * 21 | * @author Leo McCormack 22 | * @date 10.08.2020 23 | * @license ISC 24 | */ 25 | 26 | #include "ambi_roomsim.h" 27 | #include "ambi_roomsim_internal.h" 28 | 29 | -------------------------------------------------------------------------------- /examples/src/beamformer/beamformer_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file beamformer_internal.c 19 | * @brief Generates beamformers/virtual microphones in arbitrary directions 20 | * with several different beam patterns to choose from 21 | * 22 | * @author Leo McCormack 23 | * @date 17.05.2019 24 | * @license ISC 25 | */ 26 | 27 | #include "beamformer_internal.h" 28 | 29 | -------------------------------------------------------------------------------- /examples/src/binauraliser_nf/binauraliser_nf_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Michael McCrea, Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file: binauraliser_nf_internal.c 19 | * @brief Convolves input audio (up to 64 channels) with interpolated HRTFs in 20 | * the time-frequency domain, and applies optional near-field binaural 21 | * filtering, as described in [1]. 22 | * 23 | * The HRTFs are interpolated by applying amplitude-preserving VBAP gains to the 24 | * HRTF magnitude responses and inter-aural time differences (ITDs) 25 | * individually, before being re-combined. The example also allows the user to 26 | * specify an external SOFA file for the convolution, and rotations of the 27 | * source directions to accomodate head-tracking. 28 | * 29 | * @see [1] S. Spagnol, E. Tavazzi, and F. Avanzini, “Distance rendering and 30 | * perception of nearby virtual sound sources with a near-field filter 31 | * model,” Applied Acoustics, vol. 115, pp. 61–73, Jan. 2017, 32 | * doi: 10.1016/j.apacoust.2016.08.015. 33 | * 34 | * @author Michael McCrea, Leo McCormack 35 | * @date 22.02.2022 36 | * @license ISC 37 | */ 38 | 39 | #include "binauraliser_nf_internal.h" 40 | 41 | void binauraliserNF_initTFT 42 | ( 43 | void* const hBin 44 | ) 45 | { 46 | binauraliserNF_data *pData = (binauraliserNF_data*)(hBin); 47 | 48 | if(pData->hSTFT==NULL) 49 | afSTFT_create(&(pData->hSTFT), pData->new_nSources, pData->new_nSources * NUM_EARS, HOP_SIZE, 0, 1, AFSTFT_BANDS_CH_TIME); 50 | else if(pData->new_nSources!=pData->nSources){ 51 | afSTFT_channelChange(pData->hSTFT, pData->new_nSources, pData->new_nSources * NUM_EARS); 52 | afSTFT_clearBuffers(pData->hSTFT); 53 | } 54 | pData->nSources = pData->new_nSources; 55 | } 56 | 57 | void binauraliserNF_resetSourceDistances(void* const hBin) 58 | { 59 | binauraliserNF_data *pData = (binauraliserNF_data*)(hBin); 60 | 61 | for(int i=0; isrc_dists_m[i] = pData->farfield_thresh_m * pData->farfield_headroom; 63 | } 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /examples/src/decorrelator/decorrelator_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file decorrelator_internal.c 19 | * @brief A multi-channel decorrelator 20 | * 21 | * @author Leo McCormack 22 | * @date 07.07.2020 23 | * @license ISC 24 | */ 25 | 26 | #include "decorrelator.h" 27 | #include "decorrelator_internal.h" 28 | 29 | void decorrelator_setCodecStatus(void* const hDecor, CODEC_STATUS newStatus) 30 | { 31 | decorrelator_data *pData = (decorrelator_data*)(hDecor); 32 | if(newStatus==CODEC_STATUS_NOT_INITIALISED){ 33 | /* Pause until current initialisation is complete */ 34 | while(pData->codecStatus == CODEC_STATUS_INITIALISING) 35 | SAF_SLEEP(10); 36 | } 37 | pData->codecStatus = newStatus; 38 | } 39 | -------------------------------------------------------------------------------- /examples/src/matrixconv/matrixconv_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file matrixconv_internal.c 19 | * @brief A standard matrix convolver 20 | * @author Leo McCormack 21 | * @date 30.09.2019 22 | * @license ISC 23 | */ 24 | 25 | #include "matrixconv.h" 26 | #include "matrixconv_internal.h" 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/src/matrixconv/matrixconv_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file matrixconv_internal.h 19 | * @brief A standard matrix convolver 20 | * @author Leo McCormack 21 | * @date 30.09.2019 22 | * @license ISC 23 | */ 24 | 25 | #ifndef __MATRIXCONV_INTERNAL_H_INCLUDED__ 26 | #define __MATRIXCONV_INTERNAL_H_INCLUDED__ 27 | 28 | #include "matrixconv.h" /* Include header for this example */ 29 | #include "saf.h" /* Main include header for SAF */ 30 | #include "saf_externals.h" /* To also include SAF dependencies (cblas etc.) */ 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif /* __cplusplus */ 35 | 36 | /* ========================================================================== */ 37 | /* Internal Parameters */ 38 | /* ========================================================================== */ 39 | 40 | #define MIN_FRAME_SIZE ( 512 ) /**< Minimum framesize, in time-domain samples */ 41 | #define MAX_FRAME_SIZE ( 8192 ) /**< Maximum framesize, in time-domain samples */ 42 | #define MAX_NUM_CHANNELS_FOR_WAV ( 1024 ) /**< Minimum number of channels supported by WAV files */ 43 | 44 | /* ========================================================================== */ 45 | /* Structures */ 46 | /* ========================================================================== */ 47 | 48 | /** Main structure for matrixconv */ 49 | typedef struct _matrixconv 50 | { 51 | /* FIFO buffers */ 52 | int FIFO_idx; /**< FIFO buffer index */ 53 | float** inFIFO; /**< Input FIFO buffer */ 54 | float** outFIFO; /**< Output FIFO buffer */ 55 | 56 | /* input/output buffers */ 57 | float** inputFrameTD; /**< Input buffer; #MAX_NUM_CHANNELS x hostBlockSize_clamped */ 58 | float** outputFrameTD; /**< Output buffer; #MAX_NUM_CHANNELS x hostBlockSize_clamped */ 59 | 60 | /* internal */ 61 | void* hMatrixConv; /**< saf_matrixConv handle */ 62 | int hostBlockSize; /**< current host block size */ 63 | int hostBlockSize_clamped; /**< Clamped between #MIN_FRAME_SIZE and #MAX_FRAME_SIZE */ 64 | float* filters; /**< the matrix of filters; FLAT: nOutputChannels x nInputChannels x filter_length */ 65 | int nfilters; /**< the number of filters (nOutputChannels x nInputChannels) */ 66 | int input_wav_length; /**< length of the wav files loaded in samples (inputs are concatenated) */ 67 | int filter_length; /**< length of the filters (input_wav_length/nInputChannels) */ 68 | int filter_fs; /**< current samplerate of the filters */ 69 | int host_fs; /**< current samplerate of the host */ 70 | int reInitFilters; /**< FLAG: 0: do not reinit, 1: reinit, 2: reinit in progress */ 71 | int nOutputChannels; /**< number of output channels (same as the number of channels in the loaded wav) */ 72 | 73 | /* user parameters */ 74 | int nInputChannels; /**< number of input channels */ 75 | int enablePartitionedConv; /**< 0: disabled, 1: enabled */ 76 | 77 | } matrixconv_data; 78 | 79 | 80 | #ifdef __cplusplus 81 | } /* extern "C" { */ 82 | #endif /* __cplusplus */ 83 | 84 | #endif /* __MATRIXCONV_INTERNAL_H_INCLUDED__ */ 85 | -------------------------------------------------------------------------------- /examples/src/multiconv/multiconv_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file multiconv_internal.c 19 | * @brief A multi-channel convolver 20 | * @author Leo McCormack 21 | * @date 23.09.2019 22 | * @license ISC 23 | */ 24 | 25 | #include "multiconv.h" 26 | #include "multiconv_internal.h" 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/src/multiconv/multiconv_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file multiconv_internal.h 19 | * @brief A multi-channel convolver 20 | * @author Leo McCormack 21 | * @date 23.09.2019 22 | * @license ISC 23 | */ 24 | 25 | #ifndef __MULTICONV_INTERNAL_H_INCLUDED__ 26 | #define __MULTICONV_INTERNAL_H_INCLUDED__ 27 | 28 | #include "multiconv.h" /* Include header for this example */ 29 | #include "saf.h" /* Main include header for SAF */ 30 | #include "saf_externals.h" /* To also include SAF dependencies (cblas etc.) */ 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif /* __cplusplus */ 35 | 36 | /* ========================================================================== */ 37 | /* Internal Parameters */ 38 | /* ========================================================================== */ 39 | 40 | #define MIN_FRAME_SIZE ( 512 ) /**< Minimum framesize, in time-domain samples */ 41 | #define MAX_FRAME_SIZE ( 8192 ) /**< Maximum framesize, in time-domain samples */ 42 | 43 | /* ========================================================================== */ 44 | /* Structures */ 45 | /* ========================================================================== */ 46 | 47 | /** Main structure for multiconv */ 48 | typedef struct _multiconv 49 | { 50 | /* FIFO buffers */ 51 | int FIFO_idx; /**< FIFO buffer index */ 52 | float** inFIFO; /**< Input FIFO buffer */ 53 | float** outFIFO; /**< Output FIFO buffer */ 54 | 55 | /* Internal buffers */ 56 | float** inputFrameTD; /**< Input buffer; #MAX_NUM_CHANNELS x hostBlockSize_clamped */ 57 | float** outputFrameTD; /**< Output buffer; #MAX_NUM_CHANNELS x hostBlockSize_clamped */ 58 | 59 | /* internal */ 60 | void* hMultiConv; /**< convolver handle */ 61 | int hostBlockSize; /**< current host block size */ 62 | int hostBlockSize_clamped; /**< Clamped between #MIN_FRAME_SIZE and #MAX_FRAME_SIZE */ 63 | float* filters; /**< FLAT: nfilters x filter_length */ 64 | int nfilters; /**< Current number of FIR filters */ 65 | int filter_length; /**< length of the filters (input_wav_length/nInputChannels) */ 66 | int filter_fs; /**< current samplerate of the filters */ 67 | int host_fs; /**< current samplerate of the host */ 68 | int reInitFilters; /**< FLAG: 0: do not reinit, 1: reinit, 2: reinit in progress */ 69 | 70 | /* user parameters */ 71 | int nChannels; /**< Current number of input/output channels */ 72 | int enablePartitionedConv; /**< 1: enable partitioned convolution, 0: regular convolution (fft over the length of the filter) */ 73 | 74 | } multiconv_data; 75 | 76 | 77 | #ifdef __cplusplus 78 | } /* extern "C" { */ 79 | #endif /* __cplusplus */ 80 | 81 | #endif /* __MULTICONV_INTERNAL_H_INCLUDED__ */ 82 | -------------------------------------------------------------------------------- /examples/src/pitch_shifter/pitch_shifter_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file pitch_shifter_internal.c 19 | * @brief A very basic multichannel pitch shifter 20 | * 21 | * @author Leo McCormack 22 | * @date 05.05.2020 23 | * @license ISC 24 | */ 25 | 26 | #include "pitch_shifter.h" 27 | #include "pitch_shifter_internal.h" 28 | 29 | void pitch_shifter_setCodecStatus(void* const hPS, CODEC_STATUS newStatus) 30 | { 31 | pitch_shifter_data *pData = (pitch_shifter_data*)(hPS); 32 | if(newStatus==CODEC_STATUS_NOT_INITIALISED){ 33 | /* Pause until current initialisation is complete */ 34 | while(pData->codecStatus == CODEC_STATUS_INITIALISING) 35 | SAF_SLEEP(10); 36 | } 37 | pData->codecStatus = newStatus; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /examples/src/pitch_shifter/pitch_shifter_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file pitch_shifter_internal.h 19 | * @brief A very basic multichannel pitch shifter 20 | * 21 | * @author Leo McCormack 22 | * @date 05.05.2020 23 | * @license ISC 24 | */ 25 | 26 | #ifndef __PITCH_SHIFTER_INTERNAL_H_INCLUDED__ 27 | #define __PITCH_SHIFTER_INTERNAL_H_INCLUDED__ 28 | 29 | #include "pitch_shifter.h" /* Include header for this example */ 30 | #include "saf.h" /* Main include header for SAF */ 31 | #include "saf_externals.h" /* To also include SAF dependencies (cblas etc.) */ 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif /* __cplusplus */ 36 | 37 | /* ========================================================================== */ 38 | /* Internal Parameters */ 39 | /* ========================================================================== */ 40 | 41 | #if !defined(PITCH_SHIFTER_FRAME_SIZE) 42 | # if defined(FRAME_SIZE) /* Use the global framesize if it is specified: */ 43 | # define PITCH_SHIFTER_FRAME_SIZE ( FRAME_SIZE ) /**< Framesize, in time-domain samples */ 44 | # else /* Otherwise, the default framesize for this example is: */ 45 | # define PITCH_SHIFTER_FRAME_SIZE ( 128 ) /**< Framesize, in time-domain samples */ 46 | # endif 47 | #endif 48 | 49 | /* ========================================================================== */ 50 | /* Structures */ 51 | /* ========================================================================== */ 52 | 53 | /** Main struct for the pitch_shifter */ 54 | typedef struct _pitch_shifter 55 | { 56 | /* FIFO buffers */ 57 | int FIFO_idx; /**< FIFO buffer index */ 58 | float** inFIFO; /**< Input FIFO buffer */ 59 | float** outFIFO; /**< Output FIFO buffer */ 60 | 61 | /* internal */ 62 | void* hSmb; /**< pitch-shifter handle */ 63 | CODEC_STATUS codecStatus; /**< see #CODEC_STATUS */ 64 | float progressBar0_1; /**< Current (re)initialisation progress, between [0..1] */ 65 | char* progressBarText; /**< Current (re)initialisation step, string */ 66 | PROC_STATUS procStatus; /**< see #PROC_STATUS */ 67 | float sampleRate; /**< Host sampling rate, in Hz */ 68 | float inputFrame[MAX_NUM_CHANNELS][PITCH_SHIFTER_FRAME_SIZE]; /**< Current input frame */ 69 | float outputFrame[MAX_NUM_CHANNELS][PITCH_SHIFTER_FRAME_SIZE]; /**< Current output frame */ 70 | int new_nChannels; /**< (current value will be replaced by this after next re-init) */ 71 | int fftFrameSize; /**< FFT size */ 72 | int stepsize; /**< Hop size in samples*/ 73 | 74 | /* user parameters */ 75 | int nChannels; /**< Current number of input/output channels */ 76 | float pitchShift_factor; /**< 1: no shift, 0.5: down one octave, 2: up one octave */ 77 | PITCH_SHIFTER_FFTSIZE_OPTIONS fftsize_option; /**< see #PITCH_SHIFTER_FFTSIZE_OPTIONS */ 78 | PITCH_SHIFTER_OSAMP_OPTIONS osamp_option; /**< see #PITCH_SHIFTER_OSAMP_OPTIONS */ 79 | 80 | } pitch_shifter_data; 81 | 82 | 83 | /* ========================================================================== */ 84 | /* Internal Functions */ 85 | /* ========================================================================== */ 86 | 87 | /** Sets codec status (see #CODEC_STATUS enum) */ 88 | void pitch_shifter_setCodecStatus(void* const hPS, 89 | CODEC_STATUS newStatus); 90 | 91 | 92 | #ifdef __cplusplus 93 | } /* extern "C" { */ 94 | #endif /* __cplusplus */ 95 | 96 | #endif /* __PITCH_SHIFTER_INTERNAL_H_INCLUDED__ */ 97 | -------------------------------------------------------------------------------- /examples/src/rotator/rotator_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2018 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file rotator_internal.c 19 | * @brief A basic spherical harmonic/ Ambisonic signals rotator, based on the 20 | * recursive approach detailed in [1] 21 | * 22 | * @test test__saf_example_rotator() 23 | * 24 | * @see [1] Ivanic, J., Ruedenberg, K. (1998). Rotation Matrices for Real 25 | * Spherical Harmonics. Direct Determination by Recursion Page: 26 | * Additions and Corrections. Journal of Physical Chemistry A, 102(45), 27 | * 9099?9100. 28 | * 29 | * @author Leo McCormack 30 | * @date 02.11.2017 31 | * @license ISC 32 | */ 33 | 34 | #include "rotator.h" 35 | #include "rotator_internal.h" 36 | 37 | 38 | -------------------------------------------------------------------------------- /examples/src/spreader/spreader_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file: spreader_internal.c 19 | * @brief An arbitrary array panner (HRIRs, microphone array IRs, etc.) with 20 | * coherent and incoherent spreading modes, as described in [1]. 21 | * 22 | * @see [1] McCormack, L. Politis, A., and Pulkki, V., 2021, October. Rendering 23 | * of source spread for arbitrary playback setups based on spatial 24 | * covariance matching. In 2021 IEEE Workshop on Applications of Signal 25 | * Processing to Audio and Acoustics (WASPAA). IEEE 26 | * 27 | * @author Leo McCormack 28 | * @date 07.04.2021 29 | * @license ISC 30 | */ 31 | 32 | #include "spreader_internal.h" 33 | 34 | void spreader_setCodecStatus(void* const hSpr, CODEC_STATUS newStatus) 35 | { 36 | spreader_data *pData = (spreader_data*)(hSpr); 37 | if(newStatus==CODEC_STATUS_NOT_INITIALISED){ 38 | /* Pause until current initialisation is complete */ 39 | while(pData->codecStatus == CODEC_STATUS_INITIALISING) 40 | SAF_SLEEP(10); 41 | } 42 | pData->codecStatus = newStatus; 43 | } 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /examples/src/tvconv/tvconv_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file tvconv_internal.c 19 | * @brief A time-varying multi-channel convolver 20 | * @author Rapolas Daugintis 21 | * @date 13.07.2021 22 | */ 23 | 24 | #include "tvconv_internal.h" 25 | 26 | void tvconv_setCodecStatus(void* const hTVCnv, CODEC_STATUS newStatus) 27 | { 28 | tvconv_data *pData = (tvconv_data*)(hTVCnv); 29 | if(newStatus==CODEC_STATUS_NOT_INITIALISED){ 30 | /* Pause until current initialisation is complete */ 31 | while(pData->codecStatus == CODEC_STATUS_INITIALISING) 32 | SAF_SLEEP(10); 33 | } 34 | pData->codecStatus = newStatus; 35 | } 36 | 37 | void tvconv_findNearestNeigbour(void* const hTVCnv) 38 | { 39 | float dist = 0, minDist = 0; 40 | int i, d, min_idx = 0; 41 | tvconv_data *pData = (tvconv_data*)(hTVCnv); 42 | if (pData->nListenerPositions > 0 && pData->listenerPositions != NULL) { 43 | for(i = 0; i < pData->nListenerPositions; i++){ 44 | for(d = 0; d < NUM_DIMENSIONS; d++) 45 | dist += (pData->targetPosition[d] - pData->listenerPositions[i][d]) * 46 | (pData->targetPosition[d] - pData->listenerPositions[i][d]); 47 | 48 | if(dist < minDist || i == 0){ 49 | minDist = dist; 50 | min_idx = i; 51 | } 52 | dist = 0; 53 | } 54 | } 55 | 56 | pData->position_idx = min_idx; 57 | } 58 | 59 | void tvconv_setMinMaxDimensions(void* const hTVCnv) 60 | { 61 | int i, d; 62 | tvconv_data *pData = (tvconv_data*)(hTVCnv); 63 | if(pData->listenerPositions != NULL){ 64 | for(d = 0; d < NUM_DIMENSIONS; d++){ 65 | pData->minDimensions[d] = pData->listenerPositions[0][d]; 66 | pData->maxDimensions[d] = pData->listenerPositions[0][d]; 67 | for(i = 1; inListenerPositions; i++){ 68 | if(pData->listenerPositions[i][d] < pData->minDimensions[d]) 69 | pData->minDimensions[d] = pData->listenerPositions[i][d]; 70 | else if (pData->listenerPositions[i][d] > pData->maxDimensions[d]) 71 | pData->maxDimensions[d] = pData->listenerPositions[i][d]; 72 | } 73 | } 74 | /* resetting current position to the start */ 75 | for(d = 0; d < NUM_DIMENSIONS; d++) 76 | pData->targetPosition[d] = pData->minDimensions[d]; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /extras/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | if( ${SAF_PERFORMANCE_LIB} MATCHES "SAF_USE_INTEL_MKL_ILP64" ) 3 | add_subdirectory(safmex) 4 | else() 5 | message(STATUS "safmex disabled, since it requires \"-DSAF_PERFORMANCE_LIB=SAF_USE_INTEL_MKL_ILP64\". It is currently set to \"${SAF_PERFORMANCE_LIB}\".") 6 | endif() -------------------------------------------------------------------------------- /extras/matlab/SAF_MATLAB_CODE.md: -------------------------------------------------------------------------------- 1 | # MATLAB 2 | 3 | **extras/matlab** is a folder that contains a bunch of MATLAB functions/scripts for generating SAF database files; along with MATLAB equivalents of certain SAF functions for debugging purposes. 4 | -------------------------------------------------------------------------------- /extras/matlab/saf_default_hrirs/RUN_ME.m: -------------------------------------------------------------------------------- 1 | % A script to load HRIR data from a sofa file, and generate the .h/.c 2 | % files to be used as the default HRIR data within SAF. 3 | % 4 | % Author: Leo McCormack 5 | % Date: 04.10.2020 6 | % License: ISC 7 | 8 | close all, clear all %#ok 9 | addpath('../utils'); % for mat2c.m 10 | addpath('../saf_sofa_reader_module'); % for saf_sofa_open.m 11 | 12 | % Load SOFA file 13 | sofa = saf_sofa_open('/Users/mccorml1/Documents/HRIRs_SOFA/KemarAuralID.sofa'); 14 | 15 | % Permute as needed 16 | hrir_dirs_deg = sofa.SourcePosition(1:2,:).'; 17 | hrirs = permute(sofa.Data_IR, [3 2 1]); 18 | 19 | % Copy data into a struct 20 | structToPass.default_hrirs = single(hrirs); % nDirs x 2 x len 21 | structToPass.default_hrir_dirs_deg = single(hrir_dirs_deg); 22 | structToPass.default_N_hrir_dirs = int32(size(hrir_dirs_deg,1)); 23 | structToPass.default_hrir_len = int32(size(hrirs,3)); 24 | structToPass.default_hrir_fs = int32(sofa.Data_SamplingRate); 25 | 26 | % Specify .h/.c file export configurations 27 | filename = 'saf_default_hrirs'; 28 | dataPrepend = '__'; 29 | headerdef = '__SAF_DEFAULT_HRIRS_INCLUDED__'; 30 | headerNotice = { ... 31 | ' * Copyright 2020 Leo McCormack \n' 32 | ' * \n' 33 | ' * Permission to use, copy, modify, and/or distribute this software for any \n' 34 | ' * purpose with or without fee is hereby granted, provided that the above \n' 35 | ' * copyright notice and this permission notice appear in all copies. \n' 36 | ' * \n' 37 | ' * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH \n' 38 | ' * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY \n' 39 | ' * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, \n' 40 | ' * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM \n' 41 | ' * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR \n' 42 | ' * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR \n' 43 | ' * PERFORMANCE OF THIS SOFTWARE. \n' 44 | ' */ \n' 45 | ' \n' 46 | '/** \n' 47 | ' * @file saf_default_hrirs.h \n' 48 | ' * @ingroup HRIR \n' 49 | ' * @brief Default HRIR data \n' 50 | ' * \n' 51 | ' * The default HRIR set is a Genelec Aural ID of a KEMAR Dummy Head (@48kHz). \n' 52 | ' * Kindly provided by Aki Mäkivirta and Jaan Johansson \n' 53 | ' * \n' 54 | ' * @author Leo McCormack \n' 55 | ' * @date 17.04.2020 \n'}; 56 | 57 | % Generate the .h and .c file 58 | passAsCell = {structToPass}; 59 | mat2c(passAsCell, filename, dataPrepend, headerdef, headerNotice, '' ); 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /extras/safmex/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | message(STATUS "Configuring SAFMEX wrappers:") 2 | 3 | cmake_minimum_required(VERSION 3.15) 4 | 5 | if(SAF_MEX_CXX) 6 | add_subdirectory(CXX_API) # new experimental mex versions using c++ API 7 | endif() 8 | 9 | project(safmex LANGUAGES C) 10 | find_package(Matlab) 11 | 12 | # List of available safmex wrappers 13 | set(safmex_list 14 | safmex_afSTFT 15 | safmex_faf_IIRFilterbank 16 | safmex_generateVBAPgainTable3D 17 | safmex_getSHcomplex 18 | safmex_getSHreal 19 | safmex_latticeDecorrelator 20 | safmex_qmf) 21 | 22 | if(SAF_ENABLE_TRACKER_MODULE) 23 | set(safmex_list ${safmex_list} 24 | safmex_tracker3d) 25 | else() 26 | message(STATUS " (Disabling safmex wrappers related to the saf_tracker module)") 27 | endif() 28 | 29 | # Find number of wrappers 30 | list(LENGTH safmex_list num_wrappers) 31 | math(EXPR num_wrappers "${num_wrappers} - 1") 32 | 33 | # Loop over the wrappers 34 | foreach(current_wrapper RANGE ${num_wrappers}) 35 | # Get current example string 36 | list(GET safmex_list ${current_wrapper} current_string) 37 | 38 | message(STATUS " ${current_string}") 39 | matlab_add_mex(NAME ${current_string} SRC ${current_string}.c LINK_TO saf) 40 | 41 | endforeach() 42 | 43 | 44 | # make install safmex 45 | install(TARGETS ${safmex_list} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/ 46 | COMPONENT safmex) 47 | message(STATUS "Install safmex into ${CMAKE_CURRENT_SOURCE_DIR}/ ") 48 | set_target_properties(${safmex_list} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) 49 | 50 | #This does not work for macOS for some reason (get_filename_component behaviour is different) 51 | #if( ${SAF_PERFORMANCE_LIB} MATCHES "SAF_USE_INTEL_MKL_ILP64" ) 52 | # get_filename_component(SAF_MKL_PATH ${INTEL_MKL_LIB} DIRECTORY) 53 | # set_target_properties(${safmex_list} PROPERTIES INSTALL_RPATH ${SAF_MKL_PATH}) 54 | #endif() 55 | -------------------------------------------------------------------------------- /extras/safmex/CXX_API/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | message(STATUS "Configuring SAFMEX CXX wrappers:") 2 | 3 | cmake_minimum_required(VERSION 3.15) 4 | 5 | project(safmex LANGUAGES C CXX) 6 | set(CMAKE_CXX_STANDARD 14) 7 | find_package(Matlab) 8 | 9 | # List of available safmex wrappers 10 | set(safmex_list 11 | saf_afSTFT) 12 | # saf_faf_IIRFilterbank 13 | # saf_generateVBAPgainTable3D 14 | # saf_getSHcomplex 15 | # saf_getSHreal 16 | # saf_latticeDecorrelator 17 | # saf_qmf) 18 | 19 | #if(SAF_ENABLE_TRACKER_MODULE) 20 | # set(safmex_list ${safmex_list} 21 | # safmex_tracker3d) 22 | #else() 23 | # message(STATUS " (Disabling safmex wrappers related to the saf_tracker module)") 24 | #endif() 25 | 26 | # Find number of wrappers 27 | list(LENGTH safmex_list num_wrappers) 28 | math(EXPR num_wrappers "${num_wrappers} - 1") 29 | 30 | # Loop over the wrappers 31 | foreach(current_wrapper RANGE ${num_wrappers}) 32 | # Get current example string 33 | list(GET safmex_list ${current_wrapper} current_string) 34 | 35 | message(STATUS " ${current_string}") 36 | matlab_add_mex(NAME ${current_string} SRC ${current_string}.cpp LINK_TO saf) 37 | 38 | endforeach() 39 | 40 | 41 | # make install safmex 42 | install(TARGETS ${safmex_list} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/ 43 | COMPONENT safmex) 44 | message(STATUS "Install safmex into ${CMAKE_CURRENT_SOURCE_DIR}/ ") 45 | set_target_properties(${safmex_list} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) 46 | -------------------------------------------------------------------------------- /extras/safmex/SAFMEX.md: -------------------------------------------------------------------------------- 1 | # safmex 2 | 3 | **extras/safmex** is a collection of MEX wrappers which allow SAF functions to be called within MATLAB. 4 | 5 | Even for functions that have already been implemented in MATLAB, swapping them out for these wrappers has proved beneficial simply for the faster computations afforded by them. These wrappers also serve to bring SAF functionality to MATLAB, which is not already found in existing MATLAB libraries. 6 | 7 | ## Getting started 8 | 9 | The easiest way to build the MEX wrappers is by enabling the **SAF_BUILD_EXTRAS** flag and building them via CMake. 10 | 11 | Unix users: 12 | ``` 13 | cmake -S . -B build -DSAF_BUILD_EXTRAS=1 -DSAF_ENABLE_TRACKER_MODULE=1 14 | cd build && make -j6 15 | ``` 16 | 17 | Windows users: 18 | ``` 19 | cmake -S . -B build -G "Visual Studio 15 Win64" -DSAF_BUILD_EXTRAS=1 -DSAF_ENABLE_TRACKER_MODULE=1 20 | cd build 21 | msbuild ALL_BUILD.vcxproj /p:Configuration=Release /m 22 | ``` 23 | 24 | You can install/copy the mex files into this folder with 25 | ``` 26 | make install 27 | ``` 28 | 29 | Alternatively, the **BUILD_SAFMEX.m** script may be used to build the wrappers. However, note that since the SAF framework must be built via CMake anyway (in order to run this script), you might as well just use CMake... 30 | 31 | ## Folder structure 32 | 33 | **extras/safmex/** comprises the following: 34 | * A script, **BUILD_SAFMEX.m**, to build all of the safmex wrappers via MATLAB. 35 | * **CMakeLists.txt** for building the safmex wrappers via CMake. 36 | * A folder, **safmex_tests**, containing unit tests for the safmex wrappers. 37 | * '.c' files which are the actual MEX wrappers written in C. 38 | * '.m' files (with the same name as their '.c' counterparts) which serve as documentation for the wrappers. In the MATLAB command window, simply call: "help safmex_xxx" to view its help information. 39 | 40 | 41 | ## Dependencies 42 | 43 | You will need MATLAB version 2017b or higher installed on your system. The remaining dependencies are then the same as the requirements when building the SAF framework. 44 | 45 | Note that a few of the unit tests involve comparing the output of the safmex wrapper with that of an existing MATLAB implementation of the same function. Therefore, the following MATLAB libraries are required for running these unit tests: 46 | * [Spherical-Harmonic-Transform](https://github.com/polarch/Spherical-Harmonic-Transform) 47 | * [Higher-Order-Ambisonics](https://github.com/polarch/Higher-Order-Ambisonics) 48 | * [Vector-Base-Amplitude-Panning](https://github.com/polarch/Vector-Base-Amplitude-Panning) 49 | 50 | ## Contributing 51 | 52 | Contributions are very much welcomed and encouraged. Please feel free to add more wrappers! 53 | -------------------------------------------------------------------------------- /extras/safmex/safmex_afSTFT.m: -------------------------------------------------------------------------------- 1 | %SAFMEX_AFSTFT Alias-Free STFT filterbank 2 | % [FREQ_VECTOR, PROC_DELAY] = SAFMEX_AFSTFT(NCH_IN, NCH_OUT, HOPSIZE, 3 | % BLOCKSIZE, HYBRIDMODE, FORMAT, FS) creates the afSTFT filterbank, with 4 | % NCH_IN and NCH_OUT number of input and output channels, respectively. 5 | % 6 | % The filterbank employs a hopsize of HOPSIZE, and will process BLOCKSIZE 7 | % number of samples at a time. The flag HYBRIDMODE dictates whether the 8 | % optional hybrid-filtering is enabled, which sub-divides the lowest 4 9 | % bins into 8 hybrid-bins. The FORMAT flag dictates whether the 10 | % time-frequency data is given in nBands x nCH x time, or time x nCH 11 | % x nBands. 12 | % 13 | % SAFMEX_AFSTFT() destroys the afSTFT filterbank. 14 | % 15 | % Y = SAFMEX_AFSTFT(X) performs the forward afSTFT transform if X is 16 | % a real-valued time-domain (2D) input - resulting in complex-valued 17 | % time-frequency (3D) output Y. If Y is complex-valued time-frequency 18 | % (3D) input, then the backward/inverse afSTFT transform is performed - 19 | % resulting in real-valued time-domain (2D) output Y. 20 | % 21 | % INPUT ARGUMENTS 22 | % NCH_IN: Number of input channels 23 | % NCH_OUT: Number of output channels 24 | % HOPSIZE: Hop size, in samples 25 | % BLOCKSIZE: Block size, in samples 26 | % HYBRIDMODE: '0' disabled, '1' hybrid-mode is enabled 27 | % FORMAT '0' nBands x nCH x time, '1' time x nCH x nBands 28 | % FS Samplerate, in Hz 29 | % OUTPUT ARGUMENTS 30 | % FREQ_VECTOR: Frequency vector/centre frequencies; nBands x 1 31 | % PROC_DELAY: Processing delay, in samples 32 | % 33 | % EXAMPLE 34 | % 35 | % % User params 36 | % nCHin = 10; 37 | % nCHout = nCHin; 38 | % hopsize = 128; 39 | % blocksize = 2048*10; 40 | % hybridmode = 1; 41 | % format = 0; 42 | % fs = 48e3; 43 | % 44 | % % Create 45 | % [freqVector, procDelay] = safmex_afSTFT(nCHin, nCHout, hopsize, blocksize, hybridmode, 0, fs); 46 | % 47 | % % Forward 48 | % dataTD_ref = randn(blocksize, nCHin); 49 | % dataFD = safmex_afSTFT(dataTD_ref.'); 50 | % 51 | % % Backward 52 | % dataTD = safmex_afSTFT(dataFD); 53 | % 54 | % % Destroy 55 | % safmex_afSTFT() 56 | % 57 | % % dataTD_ref will approx. (-50dB) equal dataTD, shifted by procDelay 58 | % % samples 59 | % 60 | 61 | % 62 | % Copyright 2020 Leo McCormack 63 | % 64 | % Permission to use, copy, modify, and/or distribute this software for any 65 | % purpose with or without fee is hereby granted, provided that the above 66 | % copyright notice and this permission notice appear in all copies. 67 | % 68 | % THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 69 | % REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 70 | % AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 71 | % INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 72 | % LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 73 | % OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 74 | % PERFORMANCE OF THIS SOFTWARE. 75 | % 76 | -------------------------------------------------------------------------------- /extras/safmex/safmex_faf_IIRFilterbank.m: -------------------------------------------------------------------------------- 1 | %SAFMEX_FAF_IIRFILTERBANK Power-complementary IIR filterbank 2 | % SAFMEX_FAF_IIRFILTERBANK(ORDER, CUTOFFS, SIGLEN, FS) creates the FaF 3 | % filterbank. 4 | % 5 | % This filterbank employs power-complementary butterworth IIR filters of 6 | % order ORDER to divide a mono input signal of lenth SIGLEN. The result 7 | % is frequency band signals (also of length SIGLEN), which lay within the 8 | % cut-off frequencies CUTOFFS. 9 | % 10 | % SAFMEX_FAF_IIRFILTERBANK() destroys the FaF filterbank. 11 | % 12 | % Y = SAFMEX_FAF_IIRFILTERBANK(X) performs the filtering on mono signal X 13 | % to obtain frequency band signals Y. 14 | % 15 | % INPUT ARGUMENTS 16 | % ORDER: IIR filter order (must be 1 or 3) 17 | % CUTOFFS: Cut-off frequencies, in Hz, as column vector 18 | % SIGLEN: Signal length, in samples 19 | % FS Samplerate, in Hz 20 | % 21 | % EXAMPLE 22 | % 23 | % % User params 24 | % order = 1; 25 | % lSig = 2048*10; 26 | % fs = 48e3; 27 | % cutoffFreqs = [125 250 500 1000 2000 4000]*2/sqrt(2); 28 | % 29 | % % Create 30 | % safmex_faf_IIRFilterbank(order, cutoffFreqs.', lSig, fs); 31 | % 32 | % % Apply 33 | % Impulse = zeros(lSig, 1); Impulse(1,1) = 1; 34 | % IRs = safmex_faf_IIRFilterbank(Impulse).'; 35 | % 36 | % % The magnitude responses of IRs, should sum to ~<0.1 dB at all 37 | % % frequencies 38 | % 39 | 40 | % 41 | % Copyright 2020 Leo McCormack 42 | % 43 | % Permission to use, copy, modify, and/or distribute this software for any 44 | % purpose with or without fee is hereby granted, provided that the above 45 | % copyright notice and this permission notice appear in all copies. 46 | % 47 | % THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 48 | % REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 49 | % AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 50 | % INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 51 | % LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 52 | % OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 53 | % PERFORMANCE OF THIS SOFTWARE. 54 | % 55 | -------------------------------------------------------------------------------- /extras/safmex/safmex_generateVBAPgainTable3D.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file safmex_generateVBAPgainTable3D.c 19 | * @brief MEX wrapper for generateVBAPgainTable3D (see the .m file of the same 20 | * name for documentation) 21 | * @author Leo McCormack 22 | * @date 06.08.2020 23 | */ 24 | 25 | #include "safmex.h" 26 | 27 | /* ===================================================================== */ 28 | /* Config */ 29 | /* ===================================================================== */ 30 | 31 | #define NUM_INPUT_ARGS ( 6 ) 32 | #define NUM_OUTPUT_ARGS ( 1 ) 33 | const MEX_DATA_TYPES inputDataTypes[NUM_INPUT_ARGS] = { 34 | SM_DOUBLE_REAL_2D, 35 | SM_INT32, 36 | SM_INT32, 37 | SM_INT32, 38 | SM_INT32, 39 | SM_DOUBLE_REAL 40 | }; 41 | const MEX_DATA_TYPES outputDataTypes[NUM_OUTPUT_ARGS] = { 42 | SM_DOUBLE_REAL_2D 43 | }; 44 | 45 | 46 | /* ===================================================================== */ 47 | /* MEX Wrapper */ 48 | /* ===================================================================== */ 49 | 50 | void mexFunction 51 | ( 52 | int nlhs, /* Number of output argments */ 53 | mxArray *plhs[], /* Pointers for output arguments */ 54 | int nrhs, /* Number of input argments */ 55 | const mxArray *prhs[] /* Pointers for input arguments */ 56 | ) 57 | { 58 | /* check for proper number of arguments and input argument datatypes */ 59 | checkNumInOutArgs(nrhs, nlhs, NUM_INPUT_ARGS, NUM_OUTPUT_ARGS); 60 | checkArgDataTypes((mxArray**)prhs, (MEX_DATA_TYPES*)inputDataTypes, NUM_INPUT_ARGS); 61 | 62 | /* mex variables */ 63 | int nDims; 64 | int *pDims = NULL; 65 | 66 | /* saf variables */ 67 | float* ls_dirs_deg = NULL; 68 | float* gtable = NULL; 69 | int L, az_res_deg, el_res_deg, omitLargeTriangles, enableDummies; 70 | int N_gtable, nTriangles; 71 | float spread; 72 | 73 | /* prep */ 74 | MEXdouble2SAFsingle(prhs[0], &ls_dirs_deg, &nDims, &pDims); 75 | L = pDims[0]; 76 | az_res_deg = (int)mxGetScalar(prhs[1]); 77 | el_res_deg = (int)mxGetScalar(prhs[2]); 78 | omitLargeTriangles = (int)mxGetScalar(prhs[3]); 79 | enableDummies = (int)mxGetScalar(prhs[4]); 80 | spread = (float)mxGetScalar(prhs[5]); 81 | 82 | /* any extra checks */ 83 | if(pDims[1]!=2) 84 | mexErrMsgIdAndTxt("MyToolbox:inputError","the second dimension of the first argument should be of size: 2"); 85 | 86 | /* call SAF function */ 87 | // snprintf(message, MSG_STR_LENGTH, "L = %d,\n", L); mexPrintf(message); 88 | // snprintf(message, MSG_STR_LENGTH, "az_res_deg = %d,\n", az_res_deg); mexPrintf(message); 89 | // snprintf(message, MSG_STR_LENGTH, "el_res_deg = %d,\n", el_res_deg); mexPrintf(message); 90 | // snprintf(message, MSG_STR_LENGTH, "omitLargeTriangles = %d,\n", omitLargeTriangles); mexPrintf(message); 91 | // snprintf(message, MSG_STR_LENGTH, "enableDummies = %d,\n", enableDummies); mexPrintf(message); 92 | // snprintf(message, MSG_STR_LENGTH, "spread = %.5f,\n", spread); mexPrintf(message); 93 | generateVBAPgainTable3D(ls_dirs_deg, L, az_res_deg, el_res_deg, omitLargeTriangles, 94 | enableDummies, spread, >able, &N_gtable, &nTriangles); 95 | 96 | /* output */ 97 | nDims = 2; 98 | pDims = realloc1d(pDims, nDims*sizeof(int)); 99 | pDims[0] = N_gtable; 100 | pDims[1] = L; 101 | SAFsingle2MEXdouble(gtable, nDims, pDims, &plhs[0]); 102 | 103 | /* clean-up */ 104 | free(pDims); 105 | free(ls_dirs_deg); 106 | free(gtable); 107 | 108 | /* check output argument datatypes */ 109 | checkArgDataTypes((mxArray**)plhs, (MEX_DATA_TYPES*)outputDataTypes, NUM_OUTPUT_ARGS); 110 | } 111 | -------------------------------------------------------------------------------- /extras/safmex/safmex_generateVBAPgainTable3D.m: -------------------------------------------------------------------------------- 1 | %SAFMEX_GENERATEVBAPGAINTABLE3D computes a VBAP gain table 2 | % GTABLE = SAFMEX_GENERATEVBAPGAINTABLE3D(DIRS_DEG, AZI_RES, ELEV_RES, 3 | % OMIT_LARGE_TRIS, ENABLE_DUMMIES, SPREAD) computes a VBAP gain table 4 | % GTABLE for loudspeaker directions DIRS_DEG, for every azimuth and 5 | % elevation step AZI_RES and ELEV_RES, repectively. 6 | % 7 | % The OMIT_LARGE_TRIS flag will remove any triangles which wrap around 8 | % the sphere; ENABLE_DUMMIES will place dummy loudspeakers at +90 or -90 9 | % degrees elevation if no loudspeakers exist above +60 or -60 degrees 10 | % elevation, respectively; and SPREAD (in degrees) introduces source 11 | % spreading. 12 | % 13 | % INPUT ARGUMENTS 14 | % DIRS_DEG: Loudspeaker directions in degrees; L x 2 15 | % AZI_RES: Azimuthal resolution in degrees 16 | % ELEV_RES: Elevation resolution in degrees 17 | % OMIT_LARGE_TRIS: '0' normal triangulation, '1' remove large triangles 18 | % ENABLE_DUMMIES: '0' disabled, '1' enabled. Dummies are placed at +/-90 19 | % elevation if required 20 | % SPREAD Spreading factor in degrees, 0: VBAP, >0: MDAP 21 | % OUTPUT ARGUMENTS 22 | % GTABLE: Gain Table; nSources x L 23 | % 24 | % EXAMPLE 25 | % 26 | % N_azi = 360 / AZI_RES + 1; 27 | % aziIndex = round(mod(azi+180,360)/AZI_RES); 28 | % elevIndex = round((elev+90)/ELEV_RES); 29 | % idx3D = elevIndex*N_azi+aziIndex+1; 30 | % gains3D = GTABLE(idx3D,:); 31 | % 32 | % % Will return the gains required to pan a source to [azi, elev]. 33 | 34 | % 35 | % Copyright 2020 Leo McCormack 36 | % 37 | % Permission to use, copy, modify, and/or distribute this software for any 38 | % purpose with or without fee is hereby granted, provided that the above 39 | % copyright notice and this permission notice appear in all copies. 40 | % 41 | % THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 42 | % REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 43 | % AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 44 | % INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 45 | % LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 46 | % OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 47 | % PERFORMANCE OF THIS SOFTWARE. 48 | % 49 | -------------------------------------------------------------------------------- /extras/safmex/safmex_getSHcomplex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file safmex_getSHcomplex.c 19 | * @brief MEX wrapper for getSHcomplex (see the .m file of the same name for 20 | * documentation) 21 | * @author Leo McCormack 22 | * @date 06.08.2020 23 | */ 24 | 25 | #include "safmex.h" 26 | 27 | /* ===================================================================== */ 28 | /* Config */ 29 | /* ===================================================================== */ 30 | 31 | #define NUM_INPUT_ARGS ( 2 ) 32 | #define NUM_OUTPUT_ARGS ( 1 ) 33 | const MEX_DATA_TYPES inputDataTypes[NUM_INPUT_ARGS] = { 34 | SM_INT32, 35 | SM_DOUBLE_REAL_1D_OR_2D 36 | }; 37 | const MEX_DATA_TYPES outputDataTypes[NUM_OUTPUT_ARGS] = { 38 | SM_DOUBLE_COMPLEX_1D_OR_2D 39 | }; 40 | 41 | 42 | /* ===================================================================== */ 43 | /* MEX Wrapper */ 44 | /* ===================================================================== */ 45 | 46 | void mexFunction 47 | ( 48 | int nlhs, /* Number of output argments */ 49 | mxArray *plhs[], /* Pointers for output arguments */ 50 | int nrhs, /* Number of input argments */ 51 | const mxArray *prhs[] /* Pointers for input arguments */ 52 | ) 53 | { 54 | /* check for proper number of arguments and input argument datatypes */ 55 | checkNumInOutArgs(nrhs, nlhs, NUM_INPUT_ARGS, NUM_OUTPUT_ARGS); 56 | checkArgDataTypes((mxArray**)prhs, (MEX_DATA_TYPES*)inputDataTypes, NUM_INPUT_ARGS); 57 | 58 | /* mex variables */ 59 | int nDims; 60 | int *pDims = NULL; 61 | 62 | /* saf variables */ 63 | float* dirs_rad = NULL; 64 | float_complex* Y = NULL; 65 | int order, nSH, nDirs; 66 | 67 | /* prep */ 68 | order = (int)mxGetScalar(prhs[0]); 69 | nSH = ORDER2NSH(order); 70 | MEXdouble2SAFsingle(prhs[1], &dirs_rad, &nDims, &pDims); 71 | nDirs = pDims[0]; 72 | Y = malloc1d(nSH*nDirs*sizeof(float_complex)); 73 | 74 | /* any extra checks */ 75 | if(pDims[1]!=2) 76 | mexErrMsgIdAndTxt("MyToolbox:inputError","the second dimension of the second argument should be of size: 2"); 77 | 78 | /* call SAF function */ 79 | getSHcomplex(order, dirs_rad, nDirs, Y); 80 | 81 | /* output */ 82 | nDims = 2; 83 | pDims = realloc1d(pDims, 2*sizeof(int)); 84 | pDims[0] = nSH; 85 | pDims[1] = nDirs; 86 | SAFsingle2MEXdouble_complex(Y, nDims, pDims, &plhs[0]); 87 | 88 | /* clean-up */ 89 | free(dirs_rad); 90 | free(pDims); 91 | free(Y); 92 | 93 | /* check output argument datatypes */ 94 | checkArgDataTypes((mxArray**)plhs, (MEX_DATA_TYPES*)outputDataTypes, NUM_OUTPUT_ARGS); 95 | } 96 | -------------------------------------------------------------------------------- /extras/safmex/safmex_getSHcomplex.m: -------------------------------------------------------------------------------- 1 | %SAFMEX_GETSHCOMPLEX compute complex spherical harmonics 2 | % Y = SAFMEX_GETSHCOMPLEX(ORDER, DIRS_RAD) computes spherical harmonics Y 3 | % of order ORDER for all DIRS_RAD directions. 4 | % 5 | % The spherical harmonics are computed WITH the 1/sqrt(4*pi) term. 6 | % 7 | % INPUT ARGUMENTS 8 | % ORDER: Spherical harmonic order 9 | % DIRS_RAD: Directions on the sphere [azi, INCLINATION] convention, in 10 | % RADIANS; nDirs x 2 11 | % OUTPUT ARGUMENTS 12 | % Y: Spherical harmonics; (order+1)^2 x nDirs 13 | % 14 | 15 | % 16 | % Copyright 2020 Leo McCormack 17 | % 18 | % Permission to use, copy, modify, and/or distribute this software for any 19 | % purpose with or without fee is hereby granted, provided that the above 20 | % copyright notice and this permission notice appear in all copies. 21 | % 22 | % THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 23 | % REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 24 | % AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 25 | % INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 26 | % LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 27 | % OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 28 | % PERFORMANCE OF THIS SOFTWARE. 29 | % 30 | -------------------------------------------------------------------------------- /extras/safmex/safmex_getSHreal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file safmex_getSHreal.c 19 | * @brief MEX wrapper for getSHreal (see the .m file of the same name for 20 | * documentation) 21 | * @author Leo McCormack 22 | * @date 06.08.2020 23 | */ 24 | 25 | #include "safmex.h" 26 | 27 | /* ===================================================================== */ 28 | /* Config */ 29 | /* ===================================================================== */ 30 | 31 | #define NUM_INPUT_ARGS ( 2 ) 32 | #define NUM_OUTPUT_ARGS ( 1 ) 33 | const MEX_DATA_TYPES inputDataTypes[NUM_INPUT_ARGS] = { 34 | SM_INT32, 35 | SM_DOUBLE_REAL_1D_OR_2D 36 | }; 37 | const MEX_DATA_TYPES outputDataTypes[NUM_OUTPUT_ARGS] = { 38 | SM_DOUBLE_REAL_1D_OR_2D 39 | }; 40 | 41 | 42 | /* ===================================================================== */ 43 | /* MEX Wrapper */ 44 | /* ===================================================================== */ 45 | 46 | void mexFunction 47 | ( 48 | int nlhs, /* Number of output argments */ 49 | mxArray *plhs[], /* Pointers for output arguments */ 50 | int nrhs, /* Number of input argments */ 51 | const mxArray *prhs[] /* Pointers for input arguments */ 52 | ) 53 | { 54 | /* check for proper number of arguments and input argument datatypes */ 55 | checkNumInOutArgs(nrhs, nlhs, NUM_INPUT_ARGS, NUM_OUTPUT_ARGS); 56 | checkArgDataTypes((mxArray**)prhs, (MEX_DATA_TYPES*)inputDataTypes, NUM_INPUT_ARGS); 57 | 58 | /* mex variables */ 59 | int nDims; 60 | int *pDims = NULL; 61 | 62 | /* saf variables */ 63 | float* dirs_rad = NULL; 64 | float* Y = NULL; 65 | int order, nSH, nDirs; 66 | 67 | /* prep */ 68 | order = (int)mxGetScalar(prhs[0]); 69 | nSH = ORDER2NSH(order); 70 | MEXdouble2SAFsingle(prhs[1], &dirs_rad, &nDims, &pDims); 71 | nDirs = pDims[0]; 72 | Y = malloc1d(nSH*nDirs*sizeof(float)); 73 | 74 | /* any extra checks */ 75 | if(pDims[1]!=2) 76 | mexErrMsgIdAndTxt("MyToolbox:inputError","the second dimension of the second argument should be of size: 2"); 77 | 78 | /* call SAF function */ 79 | getSHreal(order, dirs_rad, nDirs, Y); 80 | 81 | /* output */ 82 | nDims = 2; 83 | pDims = realloc1d(pDims, 2*sizeof(int)); 84 | pDims[0] = nSH; 85 | pDims[1] = nDirs; 86 | SAFsingle2MEXdouble(Y, nDims, pDims, &plhs[0]); 87 | 88 | /* clean-up */ 89 | free(dirs_rad); 90 | free(pDims); 91 | free(Y); 92 | 93 | /* check output argument datatypes */ 94 | checkArgDataTypes((mxArray**)plhs, (MEX_DATA_TYPES*)outputDataTypes, NUM_OUTPUT_ARGS); 95 | } 96 | -------------------------------------------------------------------------------- /extras/safmex/safmex_getSHreal.m: -------------------------------------------------------------------------------- 1 | %SAFMEX_GETSHREAL compute real spherical harmonics 2 | % Y = SAFMEX_GETSHREAL(ORDER, DIRS_RAD) computes spherical harmonics Y of 3 | % order ORDER for all DIRS_RAD directions. 4 | % 5 | % The spherical harmonics are computed WITH the 1/sqrt(4*pi) term. 6 | % 7 | % INPUT ARGUMENTS 8 | % ORDER: Spherical harmonic order 9 | % DIRS_RAD: Directions on the sphere [azi, INCLINATION] convention, in 10 | % RADIANS; nDirs x 2 11 | % OUTPUT ARGUMENTS 12 | % Y: Spherical harmonics; (order+1)^2 x nDirs 13 | % 14 | 15 | % 16 | % Copyright 2020 Leo McCormack 17 | % 18 | % Permission to use, copy, modify, and/or distribute this software for any 19 | % purpose with or without fee is hereby granted, provided that the above 20 | % copyright notice and this permission notice appear in all copies. 21 | % 22 | % THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 23 | % REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 24 | % AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 25 | % INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 26 | % LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 27 | % OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 28 | % PERFORMANCE OF THIS SOFTWARE. 29 | % 30 | -------------------------------------------------------------------------------- /extras/safmex/safmex_latticeDecorrelator.m: -------------------------------------------------------------------------------- 1 | %SAFMEX_LATTICEDECORRELATOR Lattice all-pass filter based decorrelator 2 | % SAFMEX_LATTICEDECORRELATOR(FS, HOPSIZE, NCH, ORDERS, FREQCUTOFFS, 3 | % MAXDELAY, FREQVECTOR, TIMESLOTS) creates the latticeDecorrelator for 4 | % NCH number of channels. 5 | % 6 | % The decorrelator groups the input signals based on the FREQCUTOFFS 7 | % divisions, and applies a fixed delay to each grouping defined by vector 8 | % FIXEDDELAYS and lattice all-pass filters of order ORDERS. 9 | % 10 | % SAFMEX_LATTICEDECORRELATOR() destroys the latticeDecorrelator. 11 | % 12 | % Y = SAFMEX_LATTICEDECORRELATOR(X) performs the decorrelation on the 13 | % complex-valued time-frequency (3D) input X. Resulting in the 14 | % decorrelated complex-valued time-frequency (3D) output Y. The 15 | % dimensions of both X and Y, are nBands x nCH x timeslots; where nBands 16 | % is length(FREQVECTOR). 17 | % 18 | % INPUT ARGUMENTS 19 | % FS: Sampling rate 20 | % HOPSIZE: Hop size in samples 21 | % NCH: Number of channels 22 | % ORDERS Lattice all-pass filter orders (2,3,4,6,8,10,12,14,15,16,18 23 | % , or 20) per band grouping; nCutoffs x 1 24 | % FREQCUTOFFS Frequency cut-offs defining the band groupings; 25 | % nCutoffs x 1 26 | % MAXDELAY: Maximum delay in hops (TIMESLOTS) 27 | % FREQVECTOR Frequency vector; nBands x 1 */ 28 | % TIMESLOTS Number of TF frames to process at a time 29 | % 30 | % EXAMPLE 31 | % 32 | % % User params 33 | % fs = 48e3; 34 | % nCH = 6; 35 | % hopsize = 128; 36 | % blocksize = 2048*24; 37 | % orders = [20 15 6 3].'; 38 | % freqCutoffs = [ 900 2.4e3 8e3, 16e3].'; 39 | % timeslots = blocksize/hopsize; 40 | % 41 | % % Create 42 | % [freqVector, procDelay] = safmex_afSTFT(nCH, nCH, hopsize, blocksize, 1, 0, 48e3); 43 | % safmex_latticeDecorrelator(fs, hopsize, nCH, orders, freqCutoffs, maxDelay, freqVector, timeslots); 44 | % 45 | % % Forward TF transform 46 | % dataTD_ref = randn(blocksize, nCH); 47 | % dataFD = safmex_afSTFT(dataTD_ref.'); 48 | % 49 | % % Decorrelate 50 | % dataFD = safmex_latticeDecorrelator(dataFD); 51 | % 52 | % % Inverse TF transform 53 | % dataTD = safmex_afSTFT(dataFD); 54 | % dataTD_ref = dataTD_ref(1:end-procDelay,1); 55 | % dataTD = dataTD(1,procDelay+1:end).'; 56 | % 57 | % % Destroy 58 | % safmex_afSTFT(); 59 | % safmex_latticeDecorrelator(); 60 | % 61 | % % the interchannel coherence (ICC) between dataTD_ref and dataTD be 62 | % around ~0 63 | % 64 | 65 | % 66 | % Copyright 2020 Leo McCormack 67 | % 68 | % Permission to use, copy, modify, and/or distribute this software for any 69 | % purpose with or without fee is hereby granted, provided that the above 70 | % copyright notice and this permission notice appear in all copies. 71 | % 72 | % THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 73 | % REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 74 | % AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 75 | % INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 76 | % LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 77 | % OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 78 | % PERFORMANCE OF THIS SOFTWARE. 79 | % 80 | -------------------------------------------------------------------------------- /extras/safmex/safmex_qmf.m: -------------------------------------------------------------------------------- 1 | %SAFMEX_QMF Quadrature-Mirror Filterbank (QMF) 2 | % [FREQ_VECTOR, PROC_DELAY] = SAFMEX_QMF(NCH_IN, NCH_OUT, HOPSIZE, 3 | % BLOCKSIZE, HYBRIDMODE, FORMAT, FS) creates an the QMF filterbank, with 4 | % NCH_IN and NCH_OUT number of input and output channels, respectively. 5 | % 6 | % The filterbank employs a hopsize of HOPSIZE, and will process BLOCKSIZE 7 | % number of samples at a time. The flag HYBRIDMODE dictates whether the 8 | % optional hybrid-filtering is enabled, which sub-divides the lowest 3 9 | % QMF bands into 10 hybrid-QMF bands. The FORMAT flag dictates whether 10 | % the time-frequency data is given in nBands x nCH x time, or time x nCH 11 | % x nBands. 12 | % 13 | % SAFMEX_QMF() destroys the QMF filterbank. 14 | % 15 | % Y = SAFMEX_QMF(X) performs the forward transform (QMF analysis) if X is 16 | % a real-valued time-domain (2D) input - resulting in complex-valued 17 | % time-frequency (3D) output Y. If Y is complex-valued time-frequency 18 | % (3D) input, then the backward transform (QMF synthesis) is performed - 19 | % resulting in real-valued time-domain (2D) output Y. 20 | % 21 | % INPUT ARGUMENTS 22 | % NCH_IN: Number of input channels 23 | % NCH_OUT: Number of output channels 24 | % HOPSIZE: Hop size, in samples 25 | % BLOCKSIZE: Block size, in samples 26 | % HYBRIDMODE: '0' disabled, '1' hybrid-mode is enabled 27 | % FORMAT '0' nBands x nCH x time, '1' time x nCH x nBands 28 | % FS Samplerate, in Hz 29 | % OUTPUT ARGUMENTS 30 | % FREQ_VECTOR: Frequency vector/centre frequencies; nBands x 1 31 | % PROC_DELAY: Processing delay, in samples 32 | % 33 | % EXAMPLE 34 | % 35 | % % User params 36 | % nCHin = 10; 37 | % nCHout = nCHin; 38 | % hopsize = 128; 39 | % blocksize = 2048*10; 40 | % hybridmode = 1; 41 | % format = 0; 42 | % fs = 48e3; 43 | % 44 | % % Create 45 | % [freqVector, procDelay] = safmex_qmf(nCHin, nCHout, hopsize, blocksize, hybridmode, 0, fs); 46 | % 47 | % % Forward 48 | % dataTD_ref = randn(blocksize, nCHin); 49 | % dataFD = safmex_qmf(dataTD_ref.'); 50 | % 51 | % % Backward 52 | % dataTD = safmex_qmf(dataFD); 53 | % 54 | % % Destroy 55 | % safmex_qmf() 56 | % 57 | % % dataTD_ref will approx. (-50dB) equal dataTD, shifted by procDelay 58 | % % samples 59 | % 60 | 61 | % 62 | % Copyright 2020 Leo McCormack 63 | % 64 | % Permission to use, copy, modify, and/or distribute this software for any 65 | % purpose with or without fee is hereby granted, provided that the above 66 | % copyright notice and this permission notice appear in all copies. 67 | % 68 | % THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 69 | % REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 70 | % AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 71 | % INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 72 | % LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 73 | % OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 74 | % PERFORMANCE OF THIS SOFTWARE. 75 | % 76 | -------------------------------------------------------------------------------- /extras/safmex/safmex_tests/SAFMEX_TESTS.m: -------------------------------------------------------------------------------- 1 | 2 | %% TEST CONFIG 3 | nTests = 0; nPass = 0; nFail = 0; 4 | tol = 1e-5; % FLT_EPSILON 5 | 6 | %% TESTS 7 | % safmex_tracker3d 8 | nTests = nTests+1; 9 | safmex_tracker3d_tests 10 | 11 | % safmex_latticeDecorrelator 12 | nCH = 6; 13 | hopsize = 128; 14 | blocksize = 2048*24; 15 | fs = 48e3; 16 | maxDelay = 10; 17 | [freqVector, procDelay] = safmex_afSTFT(nCH, nCH, hopsize, blocksize, 1, 0, 48e3); 18 | orders = [20 15 6 3].'; 19 | freqCutoffs = [ 900 2.4e3 8e3, 24e3].'; 20 | timeslots = blocksize/hopsize; 21 | safmex_latticeDecorrelator(fs, hopsize, nCH, orders, freqCutoffs, maxDelay, freqVector, timeslots); 22 | dataTD_ref = randn(blocksize, nCH); 23 | dataFD = safmex_afSTFT(dataTD_ref.'); 24 | dataFD = safmex_latticeDecorrelator(dataFD); 25 | dataTD = safmex_afSTFT(dataFD); 26 | dataTD_ref = dataTD_ref(1:end-procDelay,1); 27 | dataTD = dataTD(1,procDelay+1:end).'; 28 | icc = (dataTD_ref.' * dataTD) / sqrt((dataTD_ref.' * dataTD_ref) * (dataTD.' * dataTD)); 29 | nTests = nTests+1; 30 | if icc<0.05, nPass=nPass+1; else, nFail=nFail+1; end 31 | safmex_afSTFT(); 32 | safmex_latticeDecorrelator(); 33 | 34 | % safmex_faf_IIRFilterbank 35 | order = 3; 36 | lSig = 2048*10; 37 | fs = 48e3; 38 | cutoffFreqs = [125 250 500 1000 2000 4000]*2/sqrt(2); 39 | safmex_faf_IIRFilterbank(order, cutoffFreqs.', lSig, fs); 40 | data_ref = zeros(lSig, 1); data_ref(1,1) = 1; 41 | data_bands = safmex_faf_IIRFilterbank(data_ref).'; 42 | figure; 43 | f = linspace(1, fs / 2, lSig / 2 + 1 ); 44 | for idx = 1:size(data_bands, 2) 45 | vTf = fft(data_bands(:, idx)) ./ fft(data_ref); 46 | vAbsTf = 20 * log10(abs(vTf(1:end / 2 + 1))); 47 | semilogx(f, vAbsTf), hold on 48 | end 49 | vYsum = sum(data_bands, 2); 50 | vTfSum = fft(vYsum) ./ fft(data_ref); 51 | vAbsTfSum = 20 * log10(abs(vTfSum(1:end / 2 + 1))); 52 | semilogx(f, vAbsTfSum, 'k'), hold on 53 | xlabel('Frequency [Hz]'), ylabel('Magnitude [dB]'), title('sum(bands) should be ~0dB') 54 | ylim([-60 10]), xlim([20 20e3]), grid on, hold off 55 | nTests = nTests+1; 56 | if max(abs(vAbsTfSum(:)))<0.1, nPass=nPass+1; else, nFail=nFail+1; end 57 | safmex_faf_IIRFilterbank(); 58 | 59 | % safmex_afSTFT 60 | tic 61 | nCHin = 6; 62 | nCHout = 13; 63 | hopsize = 128; 64 | blocksize = 2048*46; 65 | [freqVector, procDelay] = safmex_afSTFT(nCHin, nCHout, hopsize, blocksize, 1, 1, 48e3); 66 | dataTD_ref = randn(blocksize, nCHin); 67 | dataFD = safmex_afSTFT(dataTD_ref.'); 68 | dataFD = repmat(dataFD(:,1,:), [1 nCHout 1]); % copy 1st input channel to all output channels 69 | dataTD = safmex_afSTFT(dataFD); 70 | dataTD_ref = dataTD_ref(1:end-procDelay,1); 71 | dataTD = dataTD(1,procDelay+1:end).'; 72 | nTests = nTests+1; 73 | if max(abs(dataTD(:,1)-dataTD_ref(:,1)))<0.01, nPass=nPass+1; else, nFail=nFail+1; end 74 | safmex_afSTFT(); 75 | toc 76 | 77 | % safmex_qmf 78 | nCHin = 10; 79 | nCHout = 4; 80 | hopsize = 128; 81 | blocksize = 2048*20; 82 | [freqVector2, procDelay] = safmex_qmf(nCHin, nCHout, hopsize, blocksize, 1, 0, 48e3); 83 | dataTD_ref = randn(blocksize, nCHin); 84 | dataFD = safmex_qmf(dataTD_ref.'); 85 | dataFD = repmat(dataFD(:,1,:), [1 nCHout 1]); % copy 1st input channel to all output channels 86 | dataTD = safmex_qmf(dataFD); 87 | dataTD_ref = dataTD_ref(1:end-procDelay,1); 88 | dataTD = dataTD(1,procDelay+1:end).'; 89 | nTests = nTests+1; 90 | if max(abs(dataTD(:,1)-dataTD_ref(:,1)))<0.01, nPass=nPass+1; else, nFail=nFail+1; end 91 | safmex_qmf(); 92 | 93 | % safmex_generateVBAPgainTable3D 94 | [~,ls_dirs] = getTdesign(10); 95 | ls_dirs = ls_dirs*180/pi; 96 | aziElevRes = [5 5]; 97 | gtable = safmex_generateVBAPgainTable3D(ls_dirs, aziElevRes(1), aziElevRes(2), 1, 0, 0); 98 | gtable_ref = getGainTable(ls_dirs,aziElevRes,0,'vbap'); 99 | nTests = nTests+1; 100 | if max(abs(gtable_ref(:)-gtable(:)))= 1 26 | % TPARS.beta_death = 1: Prior probability of death >= 1 27 | % TPARS.dt: Elapsed time (in seconds) between observations 28 | % TPARS.W_avg_coeff: Averaging coeff for importance weights [0..1] 29 | % TPARS.FORCE_KILL_TARGETS Kill targets that are too close to eachother 30 | % TPARS.forceKillDistance: Distance at which to start killing... 31 | % TPARS.M0: Mean position and velocity priors; 6 x 1 32 | % TPARS.P0: Position and velocity variance priors; 6 x 6 33 | % TPARS.cd: Prior probability of noise, [0..1] 34 | % 35 | % EXAMPLE 36 | % 37 | % % Configure the tracker 38 | % tpars.Np = 20; 39 | % tpars.maxNactiveTargets = 4; 40 | % tpars.noiseLikelihood = 0.2; 41 | % tpars.measNoiseSD = 0.2340; 42 | % tpars.noiseSpecDen = 1.5231e-06; 43 | % tpars.ALLOW_MULTI_DEATH = 1; 44 | % tpars.init_birth = 0.1; 45 | % tpars.alpha_death = 1; 46 | % tpars.beta_death = 1; 47 | % tpars.dt = 0.02; 48 | % tpars.W_avg_coeff = 0.0; 49 | % tpars.FORCE_KILL_TARGETS = 1; 50 | % tpars.forceKillDistance = 0.25; 51 | % tpars.M0(1,1) = 1; tpars.M0(2,1) = 0; tpars.M0(3,1) = 0; 52 | % tpars.M0(4,1) = 0; tpars.M0(5,1) = 0; tpars.M0(6,1) = 0; 53 | % tpars.P0 = zeros(6); 54 | % tpars.P0(1,1) = 4; tpars.P0(2,2) = 4; tpars.P0(3,3) = 4; 55 | % tpars.P0(4,4) = 0.0014; 56 | % tpars.P0(5,5) = 0.0014; 57 | % tpars.P0(6,6) = 0.0007; 58 | % tpars.cd = 1/(4*pi); 59 | % 60 | % % Create 61 | % safmex_tracker3d(tpars); 62 | % 63 | % % Track 64 | % [target_xyz, target_IDs] = safmex_tracker3d(measurements_xyz_time_0); 65 | % [target_xyz, target_IDs] = safmex_tracker3d(measurements_xyz_time_1); 66 | % ... 67 | % [target_xyz, target_IDs] = safmex_tracker3d(measurements_xyz_time_N); 68 | % 69 | % % Destroy 70 | % safmex_tracker3d(); 71 | % 72 | 73 | % 74 | % This file is part of the saf_tracker module. 75 | % Copyright (c) 2020 - Leo McCormack 76 | % 77 | % The saf_tracker module is free software; you can redistribute it and/or 78 | % modify it under the terms of the GNU General Public License as published by 79 | % the Free Software Foundation; either version 2 of the License, or (at your 80 | % option) any later version. 81 | % 82 | % The saf_tracker module is distributed in the hope that it will be useful, but 83 | % WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 84 | % or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 85 | % more details. 86 | % 87 | % See for a copy of the GNU General Public 88 | % License. 89 | % 90 | -------------------------------------------------------------------------------- /extras/safpy/SAFPY.md: -------------------------------------------------------------------------------- 1 | # safpy 2 | 3 | **extras/safpy** is a collection of wrappers which allow SAF functions to be called within Python. 4 | 5 | https://github.com/chris-hld/SAFpy 6 | 7 | ## Contributing 8 | 9 | Contributions are very much welcomed and encouraged. Please feel free to add more wrappers! 10 | -------------------------------------------------------------------------------- /extras/safwwise/SAFWWISE.md: -------------------------------------------------------------------------------- 1 | # safwwise 2 | 3 | **extras/safwwise** is an initiative tasked with demonstrating how SAF may be integrated into [Wwise](https://www.audiokinetic.com/products/wwise/) plug-ins. The work should be viewed very much as a "proof-of-concept", and it is far from a finished product. However, it has been released as an open-source project, in the hope that it may prove useful for those interested in bringing SAF functionality to Wwise. 4 | 5 | ## plugin_template 6 | 7 | A tutorial which shows how to set up Wwise SDK and the required build tools to build a Wwise plugin for Windows. The plugin can be used in Wwise authoring or in Wwise-Unity integration (the latter isn't covered fully in depth but should be enough to get started if you know Unity and Wwise). 8 | 9 | The actual plugin doesn't do anything but can be used as a template or a "hello world" type of test to learn the development tool environment and the workflow. This is meant to get a plugin built and up and running quickly. There doesn't seem to be a lot of material covering the workflow step-by-step so hopefully this will be useful for someone. For actual development and customization to your use case and platform, please refer to Wwise SDK documentation: 10 | 11 | More information can be found [here](https://github.com/SAFrelated/plugin_template). 12 | 13 | ## ambiBIN_generic 14 | 15 | Another tutorial (which is quite experimental). It currently does not fully conform to Wwise requirements and is Windows 10 specific, but it may provide a reasonable starting point for tests and experiments with the Spatial Audio Framework (SAF) integrated within a Wwise effect plugin. 16 | 17 | This project builds a somewhat working Authoring plugin which can be tested in Wwise, but is not yet fully functional in Wwise Unity Integration (shared plugin). The Authoring plugin has a generic Wwise GUI and the DSP functionality is similar to the SPARTA suite plugin AmbiBIN (without SOFA or OSC support). 18 | 19 | More information can be found [here](https://github.com/SAFrelated/ambiBIN_generic). 20 | 21 | ## Contributing 22 | 23 | Contributions are very much welcomed and encouraged! 24 | -------------------------------------------------------------------------------- /framework/modules/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # Source for core SAF modules 3 | target_sources(${PROJECT_NAME} 4 | PRIVATE 5 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_cdf4sap/saf_cdf4sap.c 6 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_hoa/saf_hoa_internal.c 7 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_hoa/saf_hoa_internal.h 8 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_hoa/saf_hoa.c 9 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_hrir/saf_default_hrirs.c 10 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_hrir/saf_hrir.c 11 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_reverb/saf_reverb_internal.c 12 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_reverb/saf_reverb_internal.h 13 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_reverb/saf_reverb.c 14 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_sh/saf_sh_internal.c 15 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_sh/saf_sh_internal.h 16 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_sh/saf_sh.c 17 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_tracker/saf_tracker_internal.c 18 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_tracker/saf_tracker_internal.h 19 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_tracker/saf_tracker.c 20 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_bessel.c 21 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_complex.c 22 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_decor.c 23 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_fft.c 24 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_filters.c 25 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_geometry.c 26 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_latticeCoeffs.c 27 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_loudspeaker_presets.c 28 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_matrixConv.c 29 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_misc.c 30 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_pitch.c 31 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_qmf.c 32 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_sensorarray_presets.c 33 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_sort.c 34 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_veclib.c 35 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_utilities/saf_utility_dvf.c 36 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_vbap/saf_vbap_internal.c 37 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_vbap/saf_vbap_internal.h 38 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_vbap/saf_vbap.c 39 | ) 40 | 41 | # Source for optional SAF modules 42 | if(SAF_ENABLE_SOFA_READER_MODULE) 43 | add_subdirectory(saf_sofa_reader) 44 | endif() 45 | if(SAF_ENABLE_TRACKER_MODULE) 46 | target_sources(${PROJECT_NAME} 47 | PRIVATE 48 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_tracker/saf_tracker_internal.c 49 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_tracker/saf_tracker_internal.h 50 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_tracker/saf_tracker.c 51 | ) 52 | endif() 53 | if(SAF_ENABLE_HADES_MODULE) 54 | target_sources(${PROJECT_NAME} 55 | PRIVATE 56 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_hades/saf_hades_analysis.c 57 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_hades/saf_hades_internal.h 58 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_hades/saf_hades_internal.c 59 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_hades/saf_hades_synthesis.c 60 | ) 61 | endif() 62 | -------------------------------------------------------------------------------- /framework/modules/saf_hades/saf_hades.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the saf_hades module. 3 | * Copyright (c) 2021 - Leo McCormack & Janani Fernandez 4 | * 5 | * The saf_hades module is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or (at your 8 | * option) any later version. 9 | * 10 | * The saf_hades module is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 | * more details. 14 | * 15 | * See for a copy of the GNU General Public 16 | * License. 17 | */ 18 | 19 | /** 20 | *@addtogroup HADES 21 | *@{ 22 | * @file saf_hades.h 23 | * @brief Main header for the HADES module (#SAF_HADES_MODULE) 24 | * 25 | * The framework for binaural rendering of Hearing-Assistive/Augmented-reality 26 | * Devices (HADES) is described further in [1] 27 | * 28 | * @see [1] Fernandez, J., McCormack, L., Hyvärinen, P., Politis, A., and 29 | * Pulkki, V. 2022. “Enhancing binaural rendering of head-worn 30 | * microphone arrays through the use of adaptive spatial covariance 31 | * matching”, The Journal of the Acoustical Society of America 151, 32 | * 2624-2635 33 | * 34 | * @author Leo McCormack and Janani Fernandez 35 | * @date 01.02.2021 36 | * @license GNU GPLv2 37 | */ 38 | 39 | #ifndef __SAF_HADES_H_INCLUDED__ 40 | #define __SAF_HADES_H_INCLUDED__ 41 | 42 | /* 43 | * This framework for binaural rendering of Hearing-Assistive/Augmented-reality 44 | * Devices (HADES) is divided into two main stages: analysis and synthesis. 45 | * 46 | * In the analysis, spatial parameters are estimated across time and frequency 47 | * based on the input microphone array signals. 48 | */ 49 | # include "saf_hades_analysis.h" 50 | 51 | /* 52 | * In the synthesis, the output binaural signals are synthesised based on the 53 | * parameter and signal containers obtained from the analysis. 54 | */ 55 | # include "saf_hades_synthesis.h" 56 | 57 | 58 | #endif /* __SAF_HADES_H_INCLUDED__ */ 59 | 60 | /**@} */ /* doxygen addtogroup HADES */ 61 | -------------------------------------------------------------------------------- /framework/modules/saf_sofa_reader/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # Source 3 | target_sources(${PROJECT_NAME} 4 | PRIVATE 5 | ${CMAKE_CURRENT_SOURCE_DIR}/saf_sofa_reader.c 6 | ${CMAKE_CURRENT_SOURCE_DIR}/libmysofa/mysofa.c 7 | ${CMAKE_CURRENT_SOURCE_DIR}/libmysofa/internal/hdf_dataobject.c 8 | ${CMAKE_CURRENT_SOURCE_DIR}/libmysofa/internal/hdf_fractalhead.c 9 | ${CMAKE_CURRENT_SOURCE_DIR}/libmysofa/internal/hdf_reader.c 10 | ${CMAKE_CURRENT_SOURCE_DIR}/libmysofa/internal/kdtree.c 11 | ${CMAKE_CURRENT_SOURCE_DIR}/libmysofa/internal/mysofa_internal.c 12 | ) 13 | -------------------------------------------------------------------------------- /framework/modules/saf_sofa_reader/libmysofa/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016-2017, Symonics GmbH, Christian Hoene 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | (1) Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | (2) Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in 13 | the documentation and/or other materials provided with the 14 | distribution. 15 | 16 | (3)The name of the author may not be used to 17 | endorse or promote products derived from this software without 18 | specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 24 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | POSSIBILITY OF SUCH DAMAGE. 31 | 32 | -------------------------------------------------------------------------------- /framework/modules/saf_sofa_reader/libmysofa/internal/kdtree.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ``kdtree'', a library for working with kd-trees. 3 | Copyright (C) 2007-2011 John Tsiombikas 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 3. The name of the author may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 | EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 21 | OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 24 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 25 | OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef MYSOFA_KDTREE_H_ 29 | #define MYSOFA_KDTREE_H_ 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | #if defined(SAF_ENABLE_SOFA_READER_MODULE) 36 | 37 | struct kdtree; 38 | 39 | /* create a kd-tree for 3-dimensional data */ 40 | struct kdtree *kd_create(void); 41 | 42 | /* free the struct kdtree */ 43 | void kd_free(struct kdtree *tree); 44 | 45 | /* insert a node, specifying its position, and optional data */ 46 | int kd_insert(struct kdtree *tree, const float *pos, void *data); 47 | 48 | /* Find the nearest node from a given point */ 49 | int kd_nearest(struct kdtree *tree, const float *pos, void **res); 50 | 51 | #endif /* SAF_ENABLE_SOFA_READER_MODULE */ 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif /* MYSOFA_KDTREE_H_ */ 58 | -------------------------------------------------------------------------------- /framework/modules/saf_sofa_reader/libmysofa/internal/mysofa_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016-2017, Symonics GmbH, Christian Hoene 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | (1) Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | (2) Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in 14 | the documentation and/or other materials provided with the 15 | distribution. 16 | 17 | (3)The name of the author may not be used to 18 | endorse or promote products derived from this software without 19 | specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 25 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 30 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | 34 | /* 35 | * tools.h 36 | * 37 | * Created on: 13.01.2017 38 | * Author: hoene 39 | */ 40 | 41 | #ifndef MYSOFA_SRC_TOOLS_H_ 42 | #define MYSOFA_SRC_TOOLS_H_ 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | #if defined(SAF_ENABLE_SOFA_READER_MODULE) 49 | 50 | #include "../mysofa.h" 51 | #include 52 | #include 53 | 54 | int changeAttribute(struct MYSOFA_ATTRIBUTE *attr, char *name, char *value, 55 | char *newvalue); 56 | int verifyAttribute(struct MYSOFA_ATTRIBUTE *attr, char *name, char *value); 57 | char *getAttribute(struct MYSOFA_ATTRIBUTE *attr, char *name); 58 | 59 | void convertCartesianToSpherical(float *values, int elements); 60 | void convertSphericalToCartesian(float *values, int elements); 61 | 62 | #define fequals(a, b) (fabs(a - b) < 0.00001) 63 | 64 | float radius(float *cartesian); 65 | 66 | #define distance(cartesian1, cartesian2) \ 67 | (sqrtf(powf((cartesian1)[0] - (cartesian2)[0], 2.f) + \ 68 | powf((cartesian1)[1] - (cartesian2)[1], 2.f) + \ 69 | powf((cartesian1)[2] - (cartesian2)[2], 2.f))) 70 | 71 | void copyToFloat(float *out, float *in, int size); 72 | void copyFromFloat(float *out, float *in, int size); 73 | 74 | void copyArrayWeighted(float *dst, float *src, int size, float w); 75 | void addArrayWeighted(float *dst, float *src, int size, float w); 76 | void scaleArray(float *dst, int size, float w); 77 | float loudness(float *in, int size); 78 | 79 | void nsearch(const void *key, const char *base, size_t num, size_t size, 80 | int (*cmp)(const void *key, const void *elt), int *lower, 81 | int *higher); 82 | 83 | 84 | #endif /* SAF_ENABLE_SOFA_READER_MODULE */ 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /* MYSOFA_SRC_TOOLS_H_ */ 91 | -------------------------------------------------------------------------------- /framework/modules/saf_utilities/saf_utility_complex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2018 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file saf_utility_complex.c 19 | * @ingroup Utilities 20 | * @brief Contains wrappers for handling complex numbers across both 21 | * C99-compliant compilers and Microsoft Visual Compiler (MSVC) 22 | 23 | * @author Leo McCormack 24 | * @date 11.07.2016 25 | * @license ISC 26 | */ 27 | 28 | #include "saf_utility_complex.h" 29 | 30 | #if __STDC_VERSION__ >= 199901L 31 | /* for C99 (and above) compliant compilers */ 32 | 33 | /* 34 | Single-Precision Complex Operations 35 | */ 36 | inline float_complex cmplxf(float re, float im) { return re + im * I; } 37 | inline float_complex ccaddf(float_complex x, float_complex y) { return x + y; } 38 | inline float_complex craddf(float_complex x, float y) { return x + y; } 39 | inline float_complex ccsubf(float_complex x, float_complex y) { return x - y; } 40 | inline float_complex crsubf(float_complex x, float y) { return x - y; } 41 | inline float_complex ccmulf(float_complex x, float_complex y) { return x * y; } 42 | inline float_complex cccmulf(float_complex x, float_complex y, float_complex z) { return x * y * z; } 43 | inline float_complex crmulf(float_complex x, float y) { return x * y; } 44 | inline float_complex ccdivf(float_complex x, float_complex y) { return x / y; } 45 | inline float_complex crdivf(float_complex x, float y) { return x / y; } 46 | 47 | /* 48 | Double-Precision Complex Operations 49 | */ 50 | inline double_complex cmplx(double re, double im) { return re + im * I; } 51 | inline double_complex ccadd(double_complex x, double_complex y) { return x + y; } 52 | inline double_complex cradd(double_complex x, double y) { return x + y; } 53 | inline double_complex ccsub(double_complex x, double_complex y) { return x - y; } 54 | inline double_complex crsub(double_complex x, double y) { return x - y; } 55 | inline double_complex ccmul(double_complex x, double_complex y) { return x * y; } 56 | inline double_complex cccmul(double_complex x, double_complex y, double_complex z) { return x * y * z; } 57 | inline double_complex crmul(double_complex x, double y) { return x * y; } 58 | inline double_complex ccdiv(double_complex x, double_complex y) { return x / y; } 59 | inline double_complex crdiv(double_complex x, double y) { return x / y; } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /framework/modules/saf_utilities/saf_utility_pitch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | *@addtogroup Utilities 19 | *@{ 20 | * @file saf_utility_pitch.h 21 | * @brief A collection of pitch shifting algorithms 22 | * 23 | * @author Leo McCormack 24 | * @date 04.05.2020 25 | * @license ISC 26 | */ 27 | 28 | #ifndef SAF_PITCH_H_INCLUDED 29 | #define SAF_PITCH_H_INCLUDED 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif /* __cplusplus */ 34 | 35 | /* ========================================================================== */ 36 | /* SMB PitchShifter */ 37 | /* ========================================================================== */ 38 | 39 | /** 40 | * Creates an instance of SMB PitchShifter 41 | * 42 | * @note Higher FFT sizes will permit more drastic pitch shifts. Increasing the 43 | * Oversampling factor will increase latency, but also improve signal 44 | * fidelity. 45 | * 46 | * @test test__smb_pitchShifter() 47 | * 48 | * @param[in] hSmb (&) address of smb pitchShifter handle 49 | * @param[in] nCH number of channels 50 | * @param[in] fftFrameSize FFT size 51 | * @param[in] osamp Oversampling/overlapping factor 52 | * @param[in] sampleRate Sampling rate, Hz 53 | */ 54 | void smb_pitchShift_create(/* Input Arguments */ 55 | void** hSmb, 56 | int nCH, 57 | int fftFrameSize, 58 | int osamp, 59 | float sampleRate); 60 | 61 | /** 62 | * Destroys an instance of SMB PitchShifter 63 | * 64 | * @param[in] hSmb (&) address of smb pitchShifter handle 65 | */ 66 | void smb_pitchShift_destroy(/* Input Arguments */ 67 | void ** const hSmb); 68 | 69 | /** 70 | * Performs pitch shifting of the input signals, while retaining the same time 71 | * duration as the original using the algorithm detailed in [1] 72 | * 73 | * This implementation was orginally written by Stephan M. Bernsee (c) 1999-2015 74 | * distributed under the WOL license. It has been modified to better work with 75 | * frame-by-frame processing. It also supports multiple input channels and 76 | * employs saf_utility_fft.h and saf_utility_veclib.h for additional run-time 77 | * optimisations. 78 | * 79 | * @param[in] hSmb (&) smb pitchShifter handle 80 | * @param[in] pitchShift Pitch shift factor, 0.5: down 1 octave, 1: no shift, 81 | * 2: up 1 octave 82 | * @param[in] frameSize Number of samples in frame 83 | * @param[in] inFrame Input frame; FLAT: nCH x frameSize 84 | * @param[out] outFrame Output frame; FLAT: nCH x frameSize 85 | * 86 | * @see [1] http://blogs.zynaptiq.com/bernsee/pitch-shifting-using-the-ft/ 87 | * Copyright 1999-2015 Stephan M. Bernsee, The Wide Open License (WOL) 88 | */ 89 | void smb_pitchShift_apply(/* Input Arguments */ 90 | void* hSmb, 91 | float pitchShift, 92 | int frameSize, 93 | float *inFrame, 94 | /* Output Arguments */ 95 | float *outFrame); 96 | 97 | 98 | #ifdef __cplusplus 99 | }/* extern "C" */ 100 | #endif /* __cplusplus */ 101 | 102 | #endif /* SAF_PITCH_H_INCLUDED */ 103 | 104 | /**@} */ /* doxygen addtogroup Utilities */ 105 | -------------------------------------------------------------------------------- /framework/modules/saf_vbap/saf_vbap_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2018 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file saf_vbap_internal.c 19 | * @ingroup VBAP 20 | * @brief Internal source for the VBAP/MDAP module (#SAF_VBAP_MODULE) 21 | * 22 | * VBAP functions largely derived from the MATLAB library found in [1]. 23 | * 24 | * @see [1] https://github.com/polarch/Vector-Base-Amplitude-Panning 25 | * Copyright (c) 2015, Archontis Politis, BSD-3-Clause License 26 | * 27 | * @author Leo McCormack 28 | * @date 02.10.2017 29 | * @license ISC 30 | */ 31 | 32 | #include "saf_vbap.h" 33 | #include "saf_vbap_internal.h" 34 | 35 | void ccross(float a[3], float b[3], float c[3]){ 36 | c[0] = a[1]*b[2]-a[2]*b[1]; 37 | c[1] = a[2]*b[0]-a[0]*b[2]; 38 | c[2] = a[0]*b[1]-a[1]*b[0]; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /framework/modules/saf_vbap/saf_vbap_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2018 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file saf_vbap_internal.h 19 | * @ingroup VBAP 20 | * @brief Internal header for the VBAP/MDAP module (#SAF_VBAP_MODULE) 21 | * 22 | * VBAP functions largely derived from the MATLAB library found in [1]. 23 | * 24 | * @see [1] https://github.com/polarch/Vector-Base-Amplitude-Panning 25 | * Copyright (c) 2015, Archontis Politis, BSD-3-Clause License 26 | * 27 | * @author Leo McCormack 28 | * @date 02.10.2017 29 | * @license ISC 30 | */ 31 | 32 | #ifndef __SAF_VBAP_INTERNAL_H_INCLUDED__ 33 | #define __SAF_VBAP_INTERNAL_H_INCLUDED__ 34 | 35 | #include "saf_vbap.h" 36 | #include "../saf_utilities/saf_utilities.h" 37 | #include "saf_externals.h" 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif /* __cplusplus */ 42 | 43 | /** 44 | * In degrees, if no ls_dirs have elevation +/- this value, dummies are placed 45 | * at +/- 90 elevation. */ 46 | #define ADD_DUMMY_LIMIT ( 60.0f ) 47 | /** 48 | * if omitLargeTriangles==1, triangles with an aperture larger than this are 49 | * discarded */ 50 | #define APERTURE_LIMIT_DEG ( 180.0f ) 51 | 52 | /* ========================================================================== */ 53 | /* Internal Functions */ 54 | /* ========================================================================== */ 55 | 56 | /** 57 | * Cross product between two 3-element floating point vectors 58 | */ 59 | void ccross(float a[3], float b[3], float c[3]); 60 | 61 | 62 | #ifdef __cplusplus 63 | } /* extern "C" */ 64 | #endif /* __cplusplus */ 65 | 66 | #endif /* __SAF_VBAP_INTERNAL_H_INCLUDED__ */ 67 | -------------------------------------------------------------------------------- /framework/resources/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Source 2 | target_sources(${PROJECT_NAME} 3 | PRIVATE 4 | ${CMAKE_CURRENT_SOURCE_DIR}/afSTFT/afSTFT_protoFilter.h 5 | ${CMAKE_CURRENT_SOURCE_DIR}/afSTFT/afSTFTlib.c 6 | ${CMAKE_CURRENT_SOURCE_DIR}/afSTFT/afSTFT_internal.h 7 | ${CMAKE_CURRENT_SOURCE_DIR}/afSTFT/afSTFT_internal.c 8 | ${CMAKE_CURRENT_SOURCE_DIR}/convhull_3d/convhull_3d.c 9 | ${CMAKE_CURRENT_SOURCE_DIR}/kissFFT/_kiss_fft_guts.h 10 | ${CMAKE_CURRENT_SOURCE_DIR}/kissFFT/kiss_fft.c 11 | ${CMAKE_CURRENT_SOURCE_DIR}/kissFFT/kiss_fftr.c 12 | ${CMAKE_CURRENT_SOURCE_DIR}/md_malloc/md_malloc.c 13 | ${CMAKE_CURRENT_SOURCE_DIR}/speex_resampler/arch.h ${CMAKE_CURRENT_SOURCE_DIR}/speex_resampler/os_support.h ${CMAKE_CURRENT_SOURCE_DIR}/speex_resampler/resample_neon.h ${CMAKE_CURRENT_SOURCE_DIR}/speex_resampler/resample_sse.h ${CMAKE_CURRENT_SOURCE_DIR}/speex_resampler/resample.c ${CMAKE_CURRENT_SOURCE_DIR}/speex_resampler/speex_resampler.h ${CMAKE_CURRENT_SOURCE_DIR}/speex_resampler/speexdsp_types.h 14 | ${CMAKE_CURRENT_SOURCE_DIR}/zlib/adler32.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/compress.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/crc32.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/crc32.h ${CMAKE_CURRENT_SOURCE_DIR}/zlib/deflate.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/deflate.h ${CMAKE_CURRENT_SOURCE_DIR}/zlib/infback.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/inffast.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/inffast.h ${CMAKE_CURRENT_SOURCE_DIR}/zlib/inffixed.h ${CMAKE_CURRENT_SOURCE_DIR}/zlib/inflate.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/inflate.h ${CMAKE_CURRENT_SOURCE_DIR}/zlib/inftrees.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/inftrees.h ${CMAKE_CURRENT_SOURCE_DIR}/zlib/trees.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/trees.h ${CMAKE_CURRENT_SOURCE_DIR}/zlib/uncompr.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zlib/zlib.h ${CMAKE_CURRENT_SOURCE_DIR}/zlib/zutil.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/zutil.h 15 | ) 16 | -------------------------------------------------------------------------------- /framework/resources/afSTFT/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Juha Vilkamo (juha.vilkamo@aalto.fi) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /framework/resources/convhull_3d/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-18 Leo McCormack (leo.mccormack@aalto.fi) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /framework/resources/kissFFT/COPYING.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2003-2010 Mark Borgerding . All rights reserved. 2 | 3 | KISS FFT is provided under: 4 | 5 | SPDX-License-Identifier: BSD-3-Clause 6 | 7 | Being under the terms of the BSD 3-clause "New" or "Revised" License, 8 | according with: 9 | 10 | LICENSES/BSD-3-Clause 11 | 12 | -------------------------------------------------------------------------------- /framework/resources/kissFFT/kiss_fft.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved. 3 | * This file is part of KISS FFT - https://github.com/mborgerding/kissfft 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * See COPYING file for more information. 7 | */ 8 | 9 | /** 10 | * @file kiss_fft.h 11 | * @brief The default complex <-> complex FFT 12 | * 13 | * Taken from: https://github.com/mborgerding/kissfft 14 | * 15 | * @author Mark Borgerding 16 | * @license BSD 3-Clause 17 | */ 18 | 19 | #ifndef KISS_FFT_H 20 | #define KISS_FFT_H 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /* 32 | ATTENTION! 33 | If you would like a : 34 | -- a utility that will handle the caching of fft objects 35 | -- real-only (no imaginary time component ) FFT 36 | -- a multi-dimensional FFT 37 | -- a command-line utility to perform ffts 38 | -- a command-line utility to perform fast-convolution filtering 39 | 40 | Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c 41 | in the tools/ directory. 42 | */ 43 | 44 | /* User may override KISS_FFT_MALLOC and/or KISS_FFT_FREE. */ 45 | #ifdef USE_SIMD 46 | # include 47 | # define kiss_fft_scalar __m128 48 | # ifndef KISS_FFT_MALLOC 49 | # define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16) 50 | # endif 51 | # ifndef KISS_FFT_FREE 52 | # define KISS_FFT_FREE _mm_free 53 | # endif 54 | #else 55 | # ifndef KISS_FFT_MALLOC 56 | # define KISS_FFT_MALLOC malloc 57 | # endif 58 | # ifndef KISS_FFT_FREE 59 | # define KISS_FFT_FREE free 60 | # endif 61 | #endif 62 | 63 | 64 | #ifdef FIXED_POINT 65 | #include 66 | # if (FIXED_POINT == 32) 67 | # define kiss_fft_scalar int32_t 68 | # else 69 | # define kiss_fft_scalar int16_t 70 | # endif 71 | #else 72 | # ifndef kiss_fft_scalar 73 | /* default is float */ 74 | # define kiss_fft_scalar float 75 | # endif 76 | #endif 77 | 78 | /** Complex data type used by kissFFT */ 79 | typedef struct { 80 | kiss_fft_scalar r; 81 | kiss_fft_scalar i; 82 | }kiss_fft_cpx; 83 | 84 | typedef struct kiss_fft_state* kiss_fft_cfg; 85 | 86 | /** 87 | * kiss_fft_alloc 88 | * 89 | * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. 90 | * 91 | * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); 92 | * 93 | * The return value from fft_alloc is a cfg buffer used internally 94 | * by the fft routine or NULL. 95 | * 96 | * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. 97 | * The returned value should be free()d when done to avoid memory leaks. 98 | * 99 | * The state can be placed in a user supplied buffer 'mem': 100 | * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, 101 | * then the function places the cfg in mem and the size used in *lenmem 102 | * and returns mem. 103 | * 104 | * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), 105 | * then the function returns NULL and places the minimum cfg 106 | * buffer size in *lenmem. 107 | */ 108 | kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); 109 | 110 | /** 111 | * kiss_fft(cfg,in_out_buf) 112 | * 113 | * Perform an FFT on a complex input buffer. 114 | * for a forward FFT, 115 | * fin should be f[0] , f[1] , ... ,f[nfft-1] 116 | * fout will be F[0] , F[1] , ... ,F[nfft-1] 117 | * Note that each element is complex and can be accessed like 118 | * f[k].r and f[k].i 119 | */ 120 | void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); 121 | 122 | /** 123 | * A more generic version of the above function. It reads its input from every Nth sample. 124 | */ 125 | void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); 126 | 127 | /* If kiss_fft_alloc allocated a buffer, it is one contiguous 128 | buffer and can be simply free()d when no longer needed*/ 129 | #define kiss_fft_free KISS_FFT_FREE 130 | 131 | /** 132 | * Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up 133 | * your compiler output to call this before you exit. 134 | */ 135 | void kiss_fft_cleanup(void); 136 | 137 | 138 | /** 139 | * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) 140 | */ 141 | int kiss_fft_next_fast_size(int n); 142 | 143 | /* for real ffts, we need an even size */ 144 | #define kiss_fftr_next_fast_size_real(n) \ 145 | (kiss_fft_next_fast_size( ((n)+1)>>1)<<1) 146 | 147 | #ifdef __cplusplus 148 | } 149 | #endif 150 | 151 | #endif 152 | -------------------------------------------------------------------------------- /framework/resources/kissFFT/kiss_fftr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003-2004, Mark Borgerding. All rights reserved. 3 | * This file is part of KISS FFT - https://github.com/mborgerding/kissfft 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * See COPYING file for more information. 7 | */ 8 | 9 | /** 10 | * @file kiss_fftr.h 11 | * @brief The default real <-> half-complex FFT 12 | * 13 | * Taken from: https://github.com/mborgerding/kissfft 14 | * 15 | * @author Mark Borgerding 16 | * @license BSD 3-Clause 17 | */ 18 | 19 | #ifndef KISS_FTR_H 20 | #define KISS_FTR_H 21 | 22 | #include "kiss_fft.h" 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | 28 | /* 29 | 30 | Real optimized version can save about 45% cpu time vs. complex fft of a real seq. 31 | 32 | 33 | 34 | */ 35 | 36 | typedef struct kiss_fftr_state *kiss_fftr_cfg; 37 | 38 | 39 | kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem); 40 | /* 41 | nfft must be even 42 | 43 | If you don't care to allocate space, use mem = lenmem = NULL 44 | */ 45 | 46 | 47 | void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata); 48 | /* 49 | input timedata has nfft scalar points 50 | output freqdata has nfft/2+1 complex points 51 | */ 52 | 53 | void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata); 54 | /* 55 | input freqdata has nfft/2+1 complex points 56 | output timedata has nfft scalar points 57 | */ 58 | 59 | #define kiss_fftr_free KISS_FFT_FREE 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | #endif 65 | -------------------------------------------------------------------------------- /framework/resources/md_malloc/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Leo McCormack 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /framework/resources/speex_resampler/COPYING: -------------------------------------------------------------------------------- 1 | Copyright 2002-2008 Xiph.org Foundation 2 | Copyright 2002-2008 Jean-Marc Valin 3 | Copyright 2005-2007 Analog Devices Inc. 4 | Copyright 2005-2008 Commonwealth Scientific and Industrial Research 5 | Organisation (CSIRO) 6 | Copyright 1993, 2002, 2006 David Rowe 7 | Copyright 2003 EpicGames 8 | Copyright 1992-1994 Jutta Degener, Carsten Bormann 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | - Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | - Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in the 19 | documentation and/or other materials provided with the distribution. 20 | 21 | - Neither the name of the Xiph.org Foundation nor the names of its 22 | contributors may be used to endorse or promote products derived from 23 | this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 29 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | -------------------------------------------------------------------------------- /framework/resources/speex_resampler/speexdsp_types.h: -------------------------------------------------------------------------------- 1 | /* speexdsp_types.h taken from libogg */ 2 | /******************************************************************** 3 | * * 4 | * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * 5 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 6 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 7 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 8 | * * 9 | * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * 10 | * by the Xiph.Org Foundation http://www.xiph.org/ * 11 | * * 12 | ******************************************************************** 13 | 14 | function: #ifdef jail to whip a few platforms into the UNIX ideal. 15 | last mod: $Id: os_types.h 7524 2004-08-11 04:20:36Z conrad $ 16 | 17 | ********************************************************************/ 18 | /** 19 | @file speexdsp_types.h 20 | @brief Speex types 21 | @license BSD 3-Clause 22 | */ 23 | #ifndef _SPEEX_TYPES_H 24 | #define _SPEEX_TYPES_H 25 | 26 | #if defined(_WIN32) 27 | 28 | # if defined(__CYGWIN__) 29 | # include <_G_config.h> 30 | typedef _G_int32_t spx_int32_t; 31 | typedef _G_uint32_t spx_uint32_t; 32 | typedef _G_int16_t spx_int16_t; 33 | typedef _G_uint16_t spx_uint16_t; 34 | # elif defined(__MINGW32__) 35 | typedef short spx_int16_t; 36 | typedef unsigned short spx_uint16_t; 37 | typedef int spx_int32_t; 38 | typedef unsigned int spx_uint32_t; 39 | # elif defined(__MWERKS__) 40 | typedef int spx_int32_t; 41 | typedef unsigned int spx_uint32_t; 42 | typedef short spx_int16_t; 43 | typedef unsigned short spx_uint16_t; 44 | # else 45 | /* MSVC/Borland */ 46 | typedef __int32 spx_int32_t; 47 | typedef unsigned __int32 spx_uint32_t; 48 | typedef __int16 spx_int16_t; 49 | typedef unsigned __int16 spx_uint16_t; 50 | # endif 51 | 52 | #elif defined(__MACOS__) 53 | 54 | # include 55 | typedef SInt16 spx_int16_t; 56 | typedef UInt16 spx_uint16_t; 57 | typedef SInt32 spx_int32_t; 58 | typedef UInt32 spx_uint32_t; 59 | 60 | #elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ 61 | 62 | # include 63 | typedef int16_t spx_int16_t; 64 | typedef u_int16_t spx_uint16_t; 65 | typedef int32_t spx_int32_t; 66 | typedef u_int32_t spx_uint32_t; 67 | 68 | #elif defined(__BEOS__) 69 | 70 | /* Be */ 71 | # include 72 | typedef int16_t spx_int16_t; 73 | typedef u_int16_t spx_uint16_t; 74 | typedef int32_t spx_int32_t; 75 | typedef u_int32_t spx_uint32_t; 76 | 77 | #elif defined (__EMX__) 78 | 79 | /* OS/2 GCC */ 80 | typedef short spx_int16_t; 81 | typedef unsigned short spx_uint16_t; 82 | typedef int spx_int32_t; 83 | typedef unsigned int spx_uint32_t; 84 | 85 | #elif defined (DJGPP) 86 | 87 | /* DJGPP */ 88 | typedef short spx_int16_t; 89 | typedef int spx_int32_t; 90 | typedef unsigned int spx_uint32_t; 91 | 92 | #elif defined(R5900) 93 | 94 | /* PS2 EE */ 95 | typedef int spx_int32_t; 96 | typedef unsigned spx_uint32_t; 97 | typedef short spx_int16_t; 98 | 99 | #elif defined(__SYMBIAN32__) 100 | 101 | /* Symbian GCC */ 102 | typedef signed short spx_int16_t; 103 | typedef unsigned short spx_uint16_t; 104 | typedef signed int spx_int32_t; 105 | typedef unsigned int spx_uint32_t; 106 | 107 | #elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) 108 | 109 | typedef short spx_int16_t; 110 | typedef unsigned short spx_uint16_t; 111 | typedef long spx_int32_t; 112 | typedef unsigned long spx_uint32_t; 113 | 114 | #elif defined(CONFIG_TI_C6X) 115 | 116 | typedef short spx_int16_t; 117 | typedef unsigned short spx_uint16_t; 118 | typedef int spx_int32_t; 119 | typedef unsigned int spx_uint32_t; 120 | 121 | #else 122 | 123 | #include "speexdsp_config_types.h" 124 | 125 | #endif 126 | 127 | #endif /* _SPEEX_TYPES_H */ 128 | -------------------------------------------------------------------------------- /framework/resources/zlib/compress.c: -------------------------------------------------------------------------------- 1 | /* compress.c -- compress a memory buffer 2 | * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #define ZLIB_INTERNAL 9 | #include "zlib.h" 10 | 11 | /* =========================================================================== 12 | Compresses the source buffer into the destination buffer. The level 13 | parameter has the same meaning as in deflateInit. sourceLen is the byte 14 | length of the source buffer. Upon entry, destLen is the total size of the 15 | destination buffer, which must be at least 0.1% larger than sourceLen plus 16 | 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. 17 | 18 | compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 19 | memory, Z_BUF_ERROR if there was not enough room in the output buffer, 20 | Z_STREAM_ERROR if the level parameter is invalid. 21 | */ 22 | int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) 23 | Bytef *dest; 24 | uLongf *destLen; 25 | const Bytef *source; 26 | uLong sourceLen; 27 | int level; 28 | { 29 | z_stream stream; 30 | int err; 31 | const uInt max = (uInt)-1; 32 | uLong left; 33 | 34 | left = *destLen; 35 | *destLen = 0; 36 | 37 | stream.zalloc = (alloc_func)0; 38 | stream.zfree = (free_func)0; 39 | stream.opaque = (voidpf)0; 40 | 41 | err = deflateInit(&stream, level); 42 | if (err != Z_OK) return err; 43 | 44 | stream.next_out = dest; 45 | stream.avail_out = 0; 46 | stream.next_in = (z_const Bytef *)source; 47 | stream.avail_in = 0; 48 | 49 | do { 50 | if (stream.avail_out == 0) { 51 | stream.avail_out = left > (uLong)max ? max : (uInt)left; 52 | left -= stream.avail_out; 53 | } 54 | if (stream.avail_in == 0) { 55 | stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; 56 | sourceLen -= stream.avail_in; 57 | } 58 | err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); 59 | } while (err == Z_OK); 60 | 61 | *destLen = stream.total_out; 62 | deflateEnd(&stream); 63 | return err == Z_STREAM_END ? Z_OK : err; 64 | } 65 | 66 | /* =========================================================================== 67 | */ 68 | int ZEXPORT compress (dest, destLen, source, sourceLen) 69 | Bytef *dest; 70 | uLongf *destLen; 71 | const Bytef *source; 72 | uLong sourceLen; 73 | { 74 | return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); 75 | } 76 | 77 | /* =========================================================================== 78 | If the default memLevel or windowBits for deflateInit() is changed, then 79 | this function needs to be updated. 80 | */ 81 | uLong ZEXPORT compressBound (sourceLen) 82 | uLong sourceLen; 83 | { 84 | return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 85 | (sourceLen >> 25) + 13; 86 | } 87 | -------------------------------------------------------------------------------- /framework/resources/zlib/inffast.h: -------------------------------------------------------------------------------- 1 | /* inffast.h -- header to use inffast.c 2 | * Copyright (C) 1995-2003, 2010 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); 12 | -------------------------------------------------------------------------------- /framework/resources/zlib/inftrees.h: -------------------------------------------------------------------------------- 1 | /* inftrees.h -- header to use inftrees.c 2 | * Copyright (C) 1995-2005, 2010 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | /* Structure for decoding tables. Each entry provides either the 12 | information needed to do the operation requested by the code that 13 | indexed that table entry, or it provides a pointer to another 14 | table that indexes more bits of the code. op indicates whether 15 | the entry is a pointer to another table, a literal, a length or 16 | distance, an end-of-block, or an invalid code. For a table 17 | pointer, the low four bits of op is the number of index bits of 18 | that table. For a length or distance, the low four bits of op 19 | is the number of extra bits to get after the code. bits is 20 | the number of bits in this code or part of the code to drop off 21 | of the bit buffer. val is the actual byte to output in the case 22 | of a literal, the base length or distance, or the offset from 23 | the current table to the next table. Each entry is four bytes. */ 24 | typedef struct { 25 | unsigned char op; /* operation, extra bits, table bits */ 26 | unsigned char bits; /* bits in this part of the code */ 27 | unsigned short val; /* offset in table or code value */ 28 | } code; 29 | 30 | /* op values as set by inflate_table(): 31 | 00000000 - literal 32 | 0000tttt - table link, tttt != 0 is the number of table index bits 33 | 0001eeee - length or distance, eeee is the number of extra bits 34 | 01100000 - end of block 35 | 01000000 - invalid code 36 | */ 37 | 38 | /* Maximum size of the dynamic table. The maximum number of code structures is 39 | 1444, which is the sum of 852 for literal/length codes and 592 for distance 40 | codes. These values were found by exhaustive searches using the program 41 | examples/enough.c found in the zlib distribtution. The arguments to that 42 | program are the number of symbols, the initial root table size, and the 43 | maximum bit length of a code. "enough 286 9 15" for literal/length codes 44 | returns returns 852, and "enough 30 6 15" for distance codes returns 592. 45 | The initial root table size (9 or 6) is found in the fifth argument of the 46 | inflate_table() calls in inflate.c and infback.c. If the root table size is 47 | changed, then these maximum sizes would be need to be recalculated and 48 | updated. */ 49 | #define ENOUGH_LENS 852 50 | #define ENOUGH_DISTS 592 51 | #define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) 52 | 53 | /* Type of code to build for inflate_table() */ 54 | typedef enum { 55 | CODES, 56 | LENS, 57 | DISTS 58 | } codetype; 59 | 60 | int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, 61 | unsigned codes, code FAR * FAR *table, 62 | unsigned FAR *bits, unsigned short FAR *work)); 63 | -------------------------------------------------------------------------------- /framework/resources/zlib/uncompr.c: -------------------------------------------------------------------------------- 1 | /* uncompr.c -- decompress a memory buffer 2 | * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #define ZLIB_INTERNAL 9 | #include "zlib.h" 10 | 11 | /* =========================================================================== 12 | Decompresses the source buffer into the destination buffer. *sourceLen is 13 | the byte length of the source buffer. Upon entry, *destLen is the total size 14 | of the destination buffer, which must be large enough to hold the entire 15 | uncompressed data. (The size of the uncompressed data must have been saved 16 | previously by the compressor and transmitted to the decompressor by some 17 | mechanism outside the scope of this compression library.) Upon exit, 18 | *destLen is the size of the decompressed data and *sourceLen is the number 19 | of source bytes consumed. Upon return, source + *sourceLen points to the 20 | first unused input byte. 21 | 22 | uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough 23 | memory, Z_BUF_ERROR if there was not enough room in the output buffer, or 24 | Z_DATA_ERROR if the input data was corrupted, including if the input data is 25 | an incomplete zlib stream. 26 | */ 27 | int ZEXPORT uncompress2 (dest, destLen, source, sourceLen) 28 | Bytef *dest; 29 | uLongf *destLen; 30 | const Bytef *source; 31 | uLong *sourceLen; 32 | { 33 | z_stream stream; 34 | int err; 35 | const uInt max = (uInt)-1; 36 | uLong len, left; 37 | Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ 38 | 39 | len = *sourceLen; 40 | if (*destLen) { 41 | left = *destLen; 42 | *destLen = 0; 43 | } 44 | else { 45 | left = 1; 46 | dest = buf; 47 | } 48 | 49 | stream.next_in = (z_const Bytef *)source; 50 | stream.avail_in = 0; 51 | stream.zalloc = (alloc_func)0; 52 | stream.zfree = (free_func)0; 53 | stream.opaque = (voidpf)0; 54 | 55 | err = inflateInit(&stream); 56 | if (err != Z_OK) return err; 57 | 58 | stream.next_out = dest; 59 | stream.avail_out = 0; 60 | 61 | do { 62 | if (stream.avail_out == 0) { 63 | stream.avail_out = left > (uLong)max ? max : (uInt)left; 64 | left -= stream.avail_out; 65 | } 66 | if (stream.avail_in == 0) { 67 | stream.avail_in = len > (uLong)max ? max : (uInt)len; 68 | len -= stream.avail_in; 69 | } 70 | err = inflate(&stream, Z_NO_FLUSH); 71 | } while (err == Z_OK); 72 | 73 | *sourceLen -= len + stream.avail_in; 74 | if (dest != buf) 75 | *destLen = stream.total_out; 76 | else if (stream.total_out && err == Z_BUF_ERROR) 77 | left = 1; 78 | 79 | inflateEnd(&stream); 80 | return err == Z_STREAM_END ? Z_OK : 81 | err == Z_NEED_DICT ? Z_DATA_ERROR : 82 | err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : 83 | err; 84 | } 85 | 86 | int ZEXPORT uncompress (dest, destLen, source, sourceLen) 87 | Bytef *dest; 88 | uLongf *destLen; 89 | const Bytef *source; 90 | uLong sourceLen; 91 | { 92 | return uncompress2(dest, destLen, source, &sourceLen); 93 | } 94 | -------------------------------------------------------------------------------- /scripts/install-safipp.bat: -------------------------------------------------------------------------------- 1 | :: "Batch script to build and install a custom Intel IPP library for SAF" 2 | :: 3 | @echo off 4 | cd /d "%~dp0" 5 | 6 | CLS 7 | 8 | ECHO ****************************************************************************************** 9 | ECHO ************** Custom IPP library installer for the Spatial_Audio_Framework ************** 10 | ECHO ****************************************************************************************** 11 | ECHO. 12 | ECHO This batch script will build the required saf_ipp_custom library files 13 | ECHO and copy them into: 14 | ECHO - "Spatial_Audio_Framework/dependencies/Win64/lib/saf_ipp_custom.lib" 15 | ECHO - "C:/Windows/System32/saf_ipp_custom.dll". 16 | ECHO. 17 | ECHO NOTE: you will need to run this script with Administrator privileges! 18 | ECHO NOTE: python3 must also be installed on your system 19 | ECHO. 20 | 21 | :: ========================================================================= :: 22 | :: Check that MKL is installed 23 | IF NOT EXIST "C:\Program Files (x86)\Intel\oneAPI\ipp\latest\tools" ( 24 | echo Intel IPP not installed on this machine. Note that Intel IPP can be freely downloaded from here: 25 | echo "https://software.intel.com/content/www/us/en/develop/tools/oneapi/base-toolkit/download.html" 26 | EXIT /B 27 | ) 28 | 29 | :: Python 30 | echo Running build scrips 31 | python "C:/Program Files (x86)/Intel/oneAPI/ipp/latest/tools/custom_library_tool_python/main.py" -c -g -n saf_ipp_custom -p "" -ff "saf_ipp_list.txt" -arch=intel64 32 | CALL build_saf_ipp_custom_intel64.bat 33 | 34 | :: Copying files 35 | :: copy the generated .dll to a system PATH folder, and the .lib to somewhere local for you to link your application with, e.g.: 36 | echo Copying files 37 | xcopy "saf_ipp_custom.lib" "..\dependencies\Win64\lib" 38 | xcopy "saf_ipp_custom.dll" "C:\Windows\System32\" 39 | 40 | 41 | :: clean everything up: 42 | echo Cleaning up 43 | del build_saf_ipp_custom_intel64.bat export.def main.c main.obj saf_ipp_custom.dll saf_ipp_custom.exp saf_ipp_custom.lib 44 | 45 | GOTO End 46 | 47 | :End 48 | -------------------------------------------------------------------------------- /scripts/install-safipp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Help message, if no input arguments were given 5 | if [[ $# -eq 0 ]]; then 6 | cat < 28 | $ 29 | ) 30 | 31 | # SAF 32 | target_link_libraries(${PROJECT_NAME} PRIVATE saf) 33 | 34 | # SAF examples tests 35 | if(SAF_BUILD_EXAMPLES) 36 | target_compile_definitions(${PROJECT_NAME} PRIVATE SAF_ENABLE_EXAMPLES_TESTS=1) 37 | target_link_libraries(${PROJECT_NAME} 38 | PRIVATE 39 | "${example_prefix}ambi_bin" 40 | "${example_prefix}ambi_dec" 41 | "${example_prefix}ambi_drc" 42 | "${example_prefix}ambi_enc" 43 | "${example_prefix}array2sh" 44 | "${example_prefix}beamformer" 45 | "${example_prefix}binauraliser" 46 | "${example_prefix}binauraliser_nf" 47 | "${example_prefix}decorrelator" 48 | "${example_prefix}dirass" 49 | "${example_prefix}matrixconv" 50 | "${example_prefix}multiconv" 51 | "${example_prefix}panner" 52 | "${example_prefix}pitch_shifter" 53 | "${example_prefix}powermap" 54 | "${example_prefix}rotator" 55 | "${example_prefix}sldoa" 56 | "${example_prefix}spreader" 57 | ) 58 | else() 59 | message(STATUS " Note: unit tests for the SAF examples have been disabled") 60 | endif() 61 | -------------------------------------------------------------------------------- /test/include/timer.h: -------------------------------------------------------------------------------- 1 | /* timer.h - Cross-platform timer library - Public Domain - 2011 Mattias Jansson / Rampant Pixels 2 | * 3 | * This library provides a cross-platform interface to measure 4 | * elapsed time with (at least) millisecond accuracy. 5 | * 6 | * This library is put in the public domain; you can redistribute 7 | * it and/or modify it without any restrictions. 8 | * 9 | */ 10 | 11 | #pragma once 12 | 13 | /*! \file timer.h 14 | Time measurements */ 15 | 16 | #if TIMER_COMPILE 17 | #define TIMER_API 18 | #else 19 | #if __cplusplus 20 | #define TIMER_API extern "C" 21 | #else 22 | #define TIMER_API extern 23 | #endif 24 | #endif 25 | 26 | #if defined( _WIN32 ) || defined( _WIN64 ) 27 | 28 | //! Tick type 29 | typedef unsigned __int64 tick_t; 30 | 31 | #else 32 | 33 | #include 34 | //! Tick type 35 | typedef uint64_t tick_t; 36 | 37 | #endif 38 | 39 | //! Deltatime type (float or double) 40 | //typedef float deltatime_t; 41 | typedef double deltatime_t; 42 | 43 | 44 | /*! Initialize timer library */ 45 | TIMER_API int timer_lib_initialize( void ); 46 | 47 | /*! Shutdown timer library */ 48 | TIMER_API void timer_lib_shutdown( void ); 49 | 50 | /*! Get current timestamp, in ticks of system-specific frequency (queryable with timer_ticks_per_second), measured from some system-specific base timestamp 51 | and not in sync with other timestamps 52 | \return Current timestamp */ 53 | TIMER_API tick_t timer_current( void ); 54 | 55 | /*! Get elapsed time since given timestamp 56 | \param t Timestamp 57 | \return Number of seconds elapsed */ 58 | TIMER_API deltatime_t timer_elapsed( const tick_t t ); 59 | 60 | /*! Get elapsed ticks since given timestamp 61 | \param t Timestamp 62 | \return Number of ticks elapsed */ 63 | TIMER_API tick_t timer_elapsed_ticks( const tick_t t ); 64 | 65 | /*! Get timer frequency, as number of ticks per second 66 | \return Ticks per second */ 67 | TIMER_API tick_t timer_ticks_per_second( void ); 68 | 69 | /*! Get ticks as seconds (effectively calculating ticks/timer_ticks_per_second()) 70 | \param dt Deltatime in ticks 71 | \return Deltatime in seconds */ 72 | TIMER_API deltatime_t timer_ticks_to_seconds( const tick_t dt ); 73 | 74 | /*! Get system time, in milliseconds since the epoch (UNIX time) 75 | \return Current timestamp, in milliseconds */ 76 | TIMER_API tick_t timer_system( void ); 77 | 78 | -------------------------------------------------------------------------------- /test/saf_test_VS/saf_test.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /test/saf_test_VS/test.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.645 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "saf_test", "saf_test.vcxproj", "{F72378EE-1300-44EB-8472-3E0AE3AF43E8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {F72378EE-1300-44EB-8472-3E0AE3AF43E8}.Debug|x64.ActiveCfg = Debug|x64 17 | {F72378EE-1300-44EB-8472-3E0AE3AF43E8}.Debug|x64.Build.0 = Debug|x64 18 | {F72378EE-1300-44EB-8472-3E0AE3AF43E8}.Debug|x86.ActiveCfg = Debug|x64 19 | {F72378EE-1300-44EB-8472-3E0AE3AF43E8}.Debug|x86.Build.0 = Debug|x64 20 | {F72378EE-1300-44EB-8472-3E0AE3AF43E8}.Release|x64.ActiveCfg = Release|x64 21 | {F72378EE-1300-44EB-8472-3E0AE3AF43E8}.Release|x64.Build.0 = Release|x64 22 | {F72378EE-1300-44EB-8472-3E0AE3AF43E8}.Release|x86.ActiveCfg = Release|Win32 23 | {F72378EE-1300-44EB-8472-3E0AE3AF43E8}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {EDA7CB6E-0CD3-4D58-8D3F-D824AA3B892A} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /test/src/resources/timer.c: -------------------------------------------------------------------------------- 1 | /* timer.h - Cross-platform timer library - Public Domain - 2011 Mattias Jansson / Rampant Pixels 2 | * 3 | * This library provides a cross-platform interface to measure 4 | * elapsed time with (at least) millisecond accuracy. 5 | * 6 | * This library is put in the public domain; you can redistribute 7 | * it and/or modify it without any restrictions. 8 | * 9 | */ 10 | 11 | #include "saf_test.h" 12 | 13 | #define TIMER_PLATFORM_WINDOWS 0 14 | #define TIMER_PLATFORM_APPLE 0 15 | #define TIMER_PLATFORM_POSIX 0 16 | 17 | #if defined( _WIN32 ) || defined( _WIN64 ) 18 | # undef TIMER_PLATFORM_WINDOWS 19 | # define TIMER_PLATFORM_WINDOWS 1 20 | # define WIN32_LEAN_AND_MEAN 21 | # include 22 | #elif defined( __APPLE__ ) 23 | # undef TIMER_PLATFORM_APPLE 24 | # define TIMER_PLATFORM_APPLE 1 25 | # include 26 | # include 27 | static mach_timebase_info_data_t _timerlib_info; 28 | static void absolutetime_to_nanoseconds (uint64_t mach_time, uint64_t* clock ) { *clock = mach_time * _timerlib_info.numer / _timerlib_info.denom; } 29 | #else 30 | # undef TIMER_PLATFORM_POSIX 31 | # define TIMER_PLATFORM_POSIX 1 32 | # include 33 | # include 34 | # include 35 | #endif 36 | 37 | static tick_t _timerlib_freq = 0; 38 | static double _timerlib_oofreq = 0; 39 | 40 | 41 | int timer_lib_initialize( void ) 42 | { 43 | #if TIMER_PLATFORM_WINDOWS 44 | tick_t unused; 45 | if( !QueryPerformanceFrequency( (LARGE_INTEGER*)&_timerlib_freq ) || 46 | !QueryPerformanceCounter( (LARGE_INTEGER*)&unused ) ) 47 | return -1; 48 | #elif TIMER_PLATFORM_APPLE 49 | if( mach_timebase_info( &_timerlib_info ) ) 50 | return -1; 51 | _timerlib_freq = 1000000000ULL; 52 | #elif TIMER_PLATFORM_POSIX 53 | struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; 54 | if( clock_gettime( CLOCK_MONOTONIC, &ts ) ) 55 | return -1; 56 | _timerlib_freq = 1000000000ULL; 57 | #endif 58 | 59 | _timerlib_oofreq = 1.0 / (double)_timerlib_freq; 60 | 61 | return 0; 62 | } 63 | 64 | 65 | void timer_lib_shutdown( void ) 66 | { 67 | } 68 | 69 | 70 | tick_t timer_current( void ) 71 | { 72 | #if TIMER_PLATFORM_WINDOWS 73 | 74 | tick_t curclock; 75 | QueryPerformanceCounter( (LARGE_INTEGER*)&curclock ); 76 | return curclock; 77 | 78 | #elif TIMER_PLATFORM_APPLE 79 | 80 | tick_t curclock = 0; 81 | absolutetime_to_nanoseconds( mach_absolute_time(), &curclock ); 82 | return curclock; 83 | 84 | #elif TIMER_PLATFORM_POSIX 85 | 86 | struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; 87 | clock_gettime( CLOCK_MONOTONIC, &ts ); 88 | return ( (uint64_t)ts.tv_sec * 1000000000ULL ) + ts.tv_nsec; 89 | 90 | #endif 91 | } 92 | 93 | 94 | tick_t timer_ticks_per_second( void ) 95 | { 96 | return _timerlib_freq; 97 | } 98 | 99 | 100 | deltatime_t timer_elapsed( const tick_t t ) 101 | { 102 | return (deltatime_t)( (double)timer_elapsed_ticks( t ) * _timerlib_oofreq ); 103 | } 104 | 105 | 106 | tick_t timer_elapsed_ticks( const tick_t t ) 107 | { 108 | tick_t dt = 0; 109 | 110 | #if TIMER_PLATFORM_WINDOWS 111 | 112 | tick_t curclock = t; 113 | QueryPerformanceCounter( (LARGE_INTEGER*)&curclock ); 114 | dt = curclock - t; 115 | 116 | #elif TIMER_PLATFORM_APPLE 117 | 118 | tick_t curclock = t; 119 | absolutetime_to_nanoseconds( mach_absolute_time(), &curclock ); 120 | dt = curclock - t; 121 | 122 | #elif TIMER_PLATFORM_POSIX 123 | 124 | tick_t curclock; 125 | struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; 126 | clock_gettime( CLOCK_MONOTONIC, &ts ); 127 | 128 | curclock = ( (tick_t)ts.tv_sec * 1000000000ULL ) + ts.tv_nsec; 129 | dt = curclock - t; 130 | 131 | #endif 132 | 133 | return dt; 134 | } 135 | 136 | 137 | deltatime_t timer_ticks_to_seconds( const tick_t dt ) 138 | { 139 | return (deltatime_t)( (double)dt * _timerlib_oofreq ); 140 | } 141 | 142 | 143 | #if TIMER_PLATFORM_WINDOWS 144 | struct __timeb64 { 145 | __time64_t time; 146 | unsigned short millitm; 147 | short timezone; 148 | short dstflag; 149 | }; 150 | _CRTIMP errno_t __cdecl _ftime64_s(_Out_ struct __timeb64 * _Time); 151 | #endif 152 | 153 | tick_t timer_system( void ) 154 | { 155 | #if TIMER_PLATFORM_WINDOWS 156 | 157 | struct __timeb64 tb; 158 | _ftime64_s( &tb ); 159 | return ( (tick_t)tb.time * 1000ULL ) + (tick_t)tb.millitm; 160 | 161 | #elif TIMER_PLATFORM_APPLE 162 | 163 | tick_t curclock = 0; 164 | absolutetime_to_nanoseconds( mach_absolute_time(), &curclock ); 165 | return ( curclock / 1000000ULL ); 166 | 167 | #elif TIMER_PLATFORM_POSIX 168 | 169 | struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; 170 | clock_gettime( CLOCK_REALTIME, &ts ); 171 | return ( (uint64_t)ts.tv_sec * 1000ULL ) + ( ts.tv_nsec / 1000000ULL ); 172 | 173 | #endif 174 | } 175 | -------------------------------------------------------------------------------- /test/src/saf_test_wrapper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2021 Leo McCormack 3 | * 4 | * This software is dual-licensed. Please refer to the LICENCE.md file for more 5 | * information. 6 | * 7 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 8 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 9 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 10 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 11 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 12 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 13 | * PERFORMANCE OF THIS SOFTWARE. 14 | */ 15 | 16 | /** 17 | * @file saf_test_wrapper.cpp 18 | * @brief Unit test program for the Spatial_Audio_Framework 19 | * @author Leo McCormack 20 | * @date 27.04.2020 21 | * @license Mixed (module dependent) 22 | */ 23 | 24 | #include "saf_test.h" 25 | #include 26 | 27 | int main(){ 28 | /* std::cout << "(This is a C++ wrapper for running the SAF unit tests)\n\n"; */ 29 | main_test(); 30 | } 31 | -------------------------------------------------------------------------------- /test/src/test__hrir_module.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2021 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file test__hrir_module.c 19 | * @brief Unit tests for the SAF hrir module 20 | * @author Leo McCormack 21 | * @date 27.04.2020 22 | * @license ISC 23 | */ 24 | 25 | #include "saf_test.h" 26 | 27 | void test__resampleHRIRs(void){ 28 | float* hrirs_out, *hrirs_tmp; 29 | int i, j, target_fs, hrirs_out_len, hrirs_tmp_len, max_ind; 30 | 31 | /* The Speex resampler has generally quite a good compromise between quality and speed. 32 | * This tolerance is quite high, but ultimately, it's how it sounds that matters. 33 | * If SAF_USE_INTEL_IPP is defined, then the Intel IPP resampler is employed instead */ 34 | const float acceptedTolerance = 0.08f; 35 | 36 | /* Test 1 - passing a unit impulse through, and :qasserting the peak is where it should be */ 37 | float* ir; 38 | ir = calloc1d(NUM_EARS * 256, sizeof(float)); 39 | ir[10] = 1.0f; 40 | ir[256+10] = 1.0f; 41 | hrirs_out = NULL; 42 | for(i=0; i<100; i++){ 43 | resampleHRIRs((float*)ir, 1, 256, 48000, 48000, 0, &hrirs_out, &hrirs_out_len); /* 1x samplerate */ 44 | utility_simaxv(hrirs_out, hrirs_out_len, &max_ind); 45 | TEST_ASSERT_TRUE(max_ind==10); 46 | utility_simaxv(hrirs_out+hrirs_out_len, hrirs_out_len, &max_ind); 47 | TEST_ASSERT_TRUE(max_ind==10); 48 | free(hrirs_out); hrirs_out = NULL; 49 | resampleHRIRs((float*)ir, 1, 256, 48000, 96000, 0, &hrirs_out, &hrirs_out_len); /* 2x samplerate */ 50 | utility_simaxv(hrirs_out, hrirs_out_len, &max_ind); 51 | TEST_ASSERT_TRUE(max_ind==20); 52 | utility_simaxv(hrirs_out+hrirs_out_len, hrirs_out_len, &max_ind); 53 | TEST_ASSERT_TRUE(max_ind==20); 54 | free(hrirs_out); hrirs_out = NULL; 55 | resampleHRIRs((float*)ir, 1, 256, 48000, 24000, 0, &hrirs_out, &hrirs_out_len); /* 0.5x samplerate */ 56 | utility_simaxv(hrirs_out, hrirs_out_len, &max_ind); 57 | TEST_ASSERT_TRUE(max_ind==5); 58 | utility_simaxv(hrirs_out+hrirs_out_len, hrirs_out_len, &max_ind); 59 | TEST_ASSERT_TRUE(max_ind==5); 60 | free(hrirs_out); hrirs_out = NULL; 61 | } 62 | free(ir); 63 | 64 | /* Test 2 - converting 48e3 to 48e3 (i.e., no actual resampling, but still passing through the filter) */ 65 | target_fs = 48000; 66 | hrirs_out = NULL; 67 | resampleHRIRs((float*)__default_hrirs, __default_N_hrir_dirs, __default_hrir_len, __default_hrir_fs, 68 | target_fs, 0 /*do not zero pad*/, &hrirs_out, &hrirs_out_len); 69 | for(i=0; i<__default_N_hrir_dirs*NUM_EARS; i++) /* Loop over IRs */ 70 | for(j=0; jM * hrtf->R * hrtf->N; i++) 68 | TEST_ASSERT_TRUE(fabsf(sofa.DataIR[i]- hrtf->DataIR.values[i])<0.000001f); 69 | for(unsigned int i=0; iM * hrtf->C; i++) 70 | TEST_ASSERT_TRUE(fabsf(sofa.SourcePosition[i]- hrtf->SourcePosition.values[i])<0.000001f); 71 | for(unsigned int i=0; iM * hrtf->C; i++) 72 | TEST_ASSERT_TRUE(fabsf(sofa.SourcePosition[i]- hrtf->SourcePosition.values[i])<0.000001f); 73 | for(unsigned int i=0; i_I * hrtf->R; i++) 74 | TEST_ASSERT_TRUE(fabsf(sofa.DataDelay[i]- hrtf->DataDelay.values[i])<0.000001f); 75 | } 76 | 77 | saf_sofa_close(&sofa); 78 | mysofa_free(hrtf); 79 | #endif /* SAF_ENABLE_NETCDF */ 80 | } 81 | 82 | #endif /* SAF_ENABLE_SOFA_READER_MODULE */ 83 | -------------------------------------------------------------------------------- /test/src/test__vbap_module.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2021 Leo McCormack 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | * PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * @file test__vbap_module.c 19 | * @brief Unit tests for the SAF vbap module 20 | * @author Leo McCormack 21 | * @date 27.04.2020 22 | * @license ISC 23 | */ 24 | 25 | #include "saf_test.h" 26 | -------------------------------------------------------------------------------- /test/test.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/test.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | --------------------------------------------------------------------------------