Library / SDK
leomccormack/Spatial_Audio_Framework avatar
leomccormack/Spatial_Audio_Framework

Spatial_Audio_Framework: a C/C++ toolbox for ambisonics, VBAP and HRIR work

A cross-platform framework for developing spatial audio algorithms and software in C/C++

758 stars109 forksCNOASSERTION

At a glance

What is it?
The Spatial_Audio_Framework is a modular C/C++ framework for spatial audio algorithm development, with separate modules for ambisonics decoding, spherical harmonics, VBAP, HRIR processing and room simulation, built on whichever BLAS and LAPACK library your machine has. Its licensing is split, and two of its optional modules are GPLv2.
Who is it for?
The Spatial_Audio_Framework suits research and product teams writing spatial audio code in C or C++ who want ambisonics decoders, VBAP panning and HRIR handling as composable modules rather than a closed plugin suite, and who already have a BLAS and LAPACK stack to link against. It does not suit a Python or web audio team, or anyone who needs one uniform licence, because the core modules are ISC while saf_tracker and saf_hades are GPLv2.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 146 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A research project that grew into a large modular codebase

The Spatial_Audio_Framework, abbreviated SAF, is an open-source cross-platform framework for developing spatial audio algorithms and software in C/C++. Its origin story is stated plainly: it began as a resource for researchers in the field and grew into a large codebase organised as distinct modules.

Each module targets a sub-field of spatial audio, and the project names the examples: ambisonics encoding and decoding, spherical array processing, amplitude panning, HRIR processing and room simulation. The framework also leans on optimised linear algebra libraries such as Intel MKL, Apple Accelerate and OpenBLAS, and on x86 SIMD intrinsics covering SSE, AVX and AVX-512.

Two design choices follow from that background. First, the framework is a source-level library rather than an application. You add its files to your project and call into it, which is a different integration shape from linking a packaged audio library. Second, the examples directory is treated as part of the deliverable rather than as an afterthought, and those examples have also been realised as VST and LV2 plug-ins under the SPARTA banner.

The module layout is also what makes extension practical. The project states that expanding the framework is relatively straightforward thanks to the modular design, and contributions from the spatial audio community are encouraged.

Core modules under ISC, two optional modules under GPLv2

The licence situation is not uniform, and this is the detail to check first. The core module set is listed as ISC licensed: saf_hoa for higher-order ambisonics binaural and loudspeaker decoders, saf_sh for spherical harmonic and spherical array processing, saf_vbap for Vector-base Amplitude Panning, saf_cdf4sap for the Covariance Domain Framework for Spatial Audio Processing, saf_hrir for HRIR and HRTF functions such as interaural time difference estimation, HRTF interpolation and diffuse-field equalisation, saf_reverb for reverbs and room simulation, and saf_utilities for shared helpers and cross-platform wrappers.

The optional modules are where the licence changes. saf_sofa_reader, a simple SOFA file reader, is ISC. saf_tracker, a particle-filtering based tracker, is GPLv2. saf_hades, for binaural rendering of hearing-assistive and augmented reality devices, is GPLv2.

That matters for anything shipped. A GPLv2 module linked into a proprietary product pulls copyleft obligations across the combination, so a team that wants the tracker or the HADES renderer must accept those terms or keep them at arm's length. A team that only needs the ISC core has no such constraint. The repository itself carries a LICENSE.md file that GitHub's classifier could not categorise, which is a further reason to read the file rather than rely on a badge.

The distinction between the ISC core and the GPLv2 extensions is the single most consequential licence fact in the framework.

One preprocessor define decides which BLAS you are using

SAF requires any library conforming to the CBLAS and LAPACK standards, and it asks you to declare which one you linked. That is done with a single global preprocessor definition:

bash
SAF_USE_INTEL_MKL_LP64         # great option, but only for x86 architectures (using the LP64 config [int32])
SAF_USE_INTEL_MKL_ILP64        # great option, but only for x86 architectures (using the ILP64 config [int64])
SAF_USE_APPLE_ACCELERATE_LP64  # great option (x86 and ARM), but MacOSX only (using the LP64 config [int32])
SAF_USE_APPLE_ACCELERATE_ILP64 # great option (x86 and ARM), but MacOSX only (using the ILP64 config [int64])
SAF_USE_OPEN_BLAS_AND_LAPACKE  # good option, works on everything
SAF_USE_ATLAS                  # bad option (x86 and ARM), many LAPACK functions are missing
SAF_USE...                     # please get in touch if you use something else! :-)

bash

The comments are the project's own judgement of each option, and they are blunt. OpenBLAS with LAPACKE is the portable choice because it works everywhere. ATLAS is explicitly labelled a bad option with many LAPACK functions missing. The MKL and Accelerate variants are described as great options with hard limits: MKL is x86 only, Accelerate is macOS only but covers both x86 and ARM. The LP64 and ILP64 suffixes pick 32-bit or 64-bit integer configuration, so a mismatch here is a build error rather than a subtle bug.

Optional modules are switched the same way:

bash
SAF_ENABLE_SOFA_READER_MODULE  # to enable saf_sofa_reader
SAF_ENABLE_TRACKER_MODULE      # to enable saf_tracker
SAF_ENABLE_HADES_MODULE        # to enable saf_hades

bash

Further options cover Intel IPP for the DFT, FFTs and resampling, FFTW for the FFT, SIMD intrinsics for vector operations, and netCDF for loading very large SOFA files instead of libmysofa.

Adding the framework means headers, two includes and a CMake line

Using SAF is a matter of wiring, not of installing a package. Once a CBLAS and LAPACK flag is defined and the matching libraries are linked, you add the files from the framework folder to your project and put one directory on your header search path:

bash
Spatial_Audio_Framework/framework/include  

bash

The master include header then pulls in the framework, with an optional second header when you also need CBLAS and LAPACK routines and other external functions carried over:

c
#include "saf.h"
#include "saf_externals.h"  /* (Optional) To also carry over CBLAS/LAPACK routines and other external functions. */

bash

For an existing CMake workflow, the integration is two lines:

bash
add_subdirectory(Spatial_Audio_Framework)
target_link_libraries(${PROJECT_NAME} PRIVATE saf)

bash

That target name, saf, is what the linking step expects. The CMake options expose the same switches as the preprocessor defines, so a project can stay on the CMake path entirely:

bash
-DSAF_PERFORMANCE_LIB=SAF_USE_INTEL_MKL_LP64 # performance library to employ (see above)
-DSAF_ENABLE_SOFA_READER_MODULE=0            # enable/disable the saf_sofa_reader module 
-DSAF_ENABLE_TRACKER_MODULE=0                # enable/disable the saf_tracker module 
-DSAF_ENABLE_HADES_MODULE=0                  # enable/disable the saf_hades module 
-DSAF_BUILD_EXAMPLES=1                       # build saf examples
-DSAF_BUILD_EXTRAS=0                         # build safmex etc.
-DSAF_BUILD_TESTS=1                          # build unit testing program
-DSAF_USE_INTEL_IPP=0                        # link and use Intel IPP for the FFT, resampler, etc.
-DSAF_ENABLE_SIMD=0                          # enable/disable SSE3, AVX2, and/or AVX-512 support
-DSAF_ENABLE_NETCDF=0                        # enable the use of NetC

bash

Two defaults are worth noticing. SIMD is off by default even though the framework is written with SIMD intrinsics in mind, and the examples and unit testing program are on by default while the extras such as safmex are off.

Choosing FFT and SOFA backends has a size threshold

Two of the optional dependencies exist for specific reasons that the framework documents rather than leaves implicit.

Intel IPP and FFTW are both about the transform itself. Intel IPP is described as a performance option for the FFT and the resampler, FFTW as the alternative FFT library, and either can be used instead of the framework's own path. Which one to take is a platform question rather than a preference: IPP is an Intel product, FFTW is a separate widely used library.

netCDF is the other case. It is listed as optional and specifically as the way to load very large SOFA files, replacing libmysofa for that job. The SOFA reader module itself is separate and switchable, so a project that only reads small measurement files has no reason to pull in netCDF or its larger dependency tree.

The optional dependencies also extend the build matrix. Each one you enable is another library to link on every platform you ship, and the framework gives you no single configuration that covers every combination. That is the main practical cost of the design and the reason the documentation keeps the option list short and explicit.

The examples are worth mentioning for a different reason. They are included in the repository, they demonstrate the functionality, and the project describes them as possible starting points for new work, so the shortest path to a working integration is usually to read one and adapt it.

Releases on a steady line, with the last push in May 2026

The framework is not archived. The last push was on 2026-05-30, on the default branch named master, and the three most recent releases are v1.3.4 from 2025-10-04, v1.3.3 from 2025-07-13 and v1.3.2 from 2024-02-02.

The release numbering is plain and consistent, which makes it easy to target a specific version when your build depends on a particular set of modules or a particular performance library configuration. The repository also carries a ChangeLog.txt at the top level, so version-level changes are traceable rather than only visible in the diff.

Documentation is part of the repository rather than a separate site. The framework structure is documented in docs/FRAMEWORK_STRUCTURE.md, and the build and link details for the performance libraries are in docs/PERFORMANCE_LIBRARY_INSTRUCTIONS.md, which is the file to read before you start fighting a linker. The project is also published on Zenodo with a DOI, which matters for academic citation, and the doxygen-generated reference is hosted as a GitHub Pages site.

One caution for newcomers: this is a C and C++ codebase with CBLAS and LAPACK at its foundation, and the framework is happy to be used as a library, but there is no scripting or web binding in the repository, so Python users will be writing an extension rather than importing a module.

Editorial conclusion

The Spatial_Audio_Framework suits research and product teams writing spatial audio code in C or C++ who want ambisonics decoders, VBAP panning and HRIR handling as composable modules rather than a closed plugin suite, and who already have a BLAS and LAPACK stack to link against. It does not suit a Python or web audio team, or anyone who needs one uniform licence, because the core modules are ISC while saf_tracker and saf_hades are GPLv2. Before integrating it, pick your performance library definition, decide which optional modules you enable, and confirm the GPLv2 boundary is acceptable for your distribution.

Frequently asked questions

What is the Spatial_Audio_Framework used for?

It is a cross-platform C/C++ framework for developing spatial audio algorithms and software, organised into modules covering ambisonics encoding and decoding, spherical array processing, VBAP, HRIR processing and room simulation.

How do I tell the Spatial_Audio_Framework which linear algebra library to use?

You add one global preprocessor definition such as SAF_USE_INTEL_MKL_LP64, SAF_USE_APPLE_ACCELERATE_ILP64 or SAF_USE_OPEN_BLAS_AND_LAPACKE. The project notes that MKL is x86 only, Accelerate is macOS only, and OpenBLAS with LAPACKE works everywhere.

What licence applies to the Spatial_Audio_Framework modules?

The core modules and the optional saf_sofa_reader module are ISC licensed, while the optional saf_tracker and saf_hades modules are GPLv2. The repository carries a LICENSE.md file that GitHub could not classify, so the text itself is worth reading.

How do I include the Spatial_Audio_Framework in a CMake project?

Add add_subdirectory(Spatial_Audio_Framework) and link the saf target with target_link_libraries. The SAF CMake options such as SAF_PERFORMANCE_LIB and SAF_ENABLE_TRACKER_MODULE mirror the preprocessor definitions.

When is netCDF needed in the Spatial_Audio_Framework?

netCDF is optional and is for loading very large SOFA files, replacing libmysofa for that task. The SOFA reader module itself is a separate switch, SAF_ENABLE_SOFA_READER_MODULE, and is off by default in the CMake options.

Official sources

  1. Issues
  2. leomccormack/Spatial_Audio_Framework on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/leomccormack-spatial-audio-framework.svg)](https://hysenlabs.com/projects/leomccormack-spatial-audio-framework)

Was this useful?