sofamyroom

This project proposes a fast, accurate, and flexible “shoebox” room acoustics simulator that supports both specular and diffuse reflections. The simulator extends the work released by Schimmel et al., called Roomsim, by adding the rendering of Binaural Room Impulse Responses (BRIR) using arbitrary Head Related Transfer Functions (HRTFs) stored with the AES Spatially Oriented Format for Acoustics (SOFA) file format. Moreover, SofaMyRoom can be launched directly from your console of choice.

The SOFA support is possible thanks to MySofa library (hereinafter referred as libmysofa) and it can export the results of the simulation to a WAVE file.

Thanks to the Virtual Acoustic Space Traveling (VAST) framework [1], we added the possibility to systematically generate labeled datasets to train and test machine learning algorithms.

The full documentation is available at robaru.github.io/sofamyroom. A pre-print describing sofamyroom is available on arXiv.

Note (October 2026): the git history was rewritten to merge the old repositories into a single line. If you cloned sofamyroom before, please re-clone it; existing clones will not pull cleanly.

Installing sofamyroom

sofamyroom is built from source with CMake (see Building). The third-party code it needs (libmysofa, PocketFFT, SFMT) is included in the repository and compiled together with it, so the resulting program is self-contained. The only system library is zlib, which macOS, the Linux distributions and MATLAB already provide; on Ubuntu Linux the development package is needed to build (sudo apt-get install zlib1g-dev), on Windows see Building on Windows. Only 64-bit platforms are supported.

Usage

sofamyroom reads a text file with the setup parameters and writes one WAVE file per receiver in the current directory. From the repository root, after building and downloading the KEMAR HRTF set (see Testing):

build/cmake/sofamyroom data/sampleroomsetup.txt

data/sampleroomsetup.txt is a commented sample of the setup file; the paths in it (SOFA file, output name) are relative to the directory you run the command from.

The setup file

The setup file lists the room, the simulation options and the sources and receivers, one name = value; assignment per line (% starts a comment). The complete list of parameters is in the documentation. Two options concern the output: options.outputname is the first part of the name of the WAVE files (one per source-receiver pair, the extension is added by sofamyroom), and options.mex_saveaswav makes the MEX file write WAVE files instead of returning a cell array (MATLAB only).

A binaural receiver is described by a string of the form

'SOFA PATH_TO_HRTF_FILE interp=VALUE norm=VALUE resampling=VALUE delay=VALUE'

where PATH_TO_HRTF_FILE is the relative or absolute path of the .sofa file and the options are:

  • interp: interpolate the neighbouring HRTFs instead of picking the closest measured direction.

  • norm: normalise the HRTF data.

  • resampling: resample the HRTFs to options.fs.

  • delay: apply the per-ear Data.Delay stored in the SOFA file, rounded to whole samples; use it with HRTF sets whose impulse responses are time-aligned and carry the interaural time difference in Data.Delay.

A value is T[RUE], t[rue] or 1 to enable an option and F[ALSE], f[alse] or 0 to disable it (only the first character is read). All options are optional and off by default; unrecognised options are skipped and, if an option is repeated, the last value is used. Valid examples:

'SOFA ./mySofaFile.sofa'
'SOFA ./mySofaFile.sofa interp=TRUE norm=0 resampling=t'
'SOFA ./myTimeAlignedFile.sofa delay=1'

Usage with MATLAB

The MEX-file takes the same parameters as a MATLAB structure. readsetup evaluates a setup file written as a MATLAB script (data/sampleroomsetup.m, same content as the .txt sample):

addpath matlab
setup = readsetup('data/sampleroomsetup.m');
output = sofamyroom(setup);

Usage with Python

The pysofamyroom package (pip install pysofamyroom, Python 3.10 or later) drives the same library in-process with the same parameters and returns the same samples:

import pysofamyroom as smr

setup = smr.read_setup("data/sampleroomsetup.txt")   # or build a smr.Setup(...)
setup.receivers[0] = smr.Receiver.sofa("data/MIT_KEMAR_normal_pinna.sofa", (3, 5, 1.2))
brirs = smr.simulate(setup)          # brirs[source][receiver]: (n_samples, n_channels)

pysofamyroom.vast generates annotated multi-room BRIR datasets in the VAST format (examples/vast_demo.py). See the Python documentation for details.

Building SofaMyRoom

These instructions will guide you through the steps to build SofaMyRoom on your local machine. CMake is required.

Building on Windows

You can use CMake to generate a Visual Studio solution that can be used to build sofamyroom. Open a new Command Prompt window and type the following commands:

> cd build
> cmake ../src -G"Visual Studio 16 2019" -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake

zlib must be available to the compiler; the command above takes it from vcpkg (vcpkg install zlib). To know how to generate solutions for other versions of Visual Studio, type cmake --help.

Building on Ubuntu Linux

You can use CMake to generate a Makefile for sofamyroom. Open a new Terminal window and type the following commands:

cd build
cmake ../src -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=BUILD_TYPE
make

CMAKE_BUILD_TYPE can be Debug, Release or Unittest. If CMAKE_BUILD_TYPE is not set, the default build type is Release. Before building the project, install the zlib headers:

sudo apt-get install zlib1g-dev

Building on MacOS

You can use CMake to generate a XCode project. Open a new Terminal window and type the following commands:

cd sofamyroom/build
cmake ../src -G"XCode"

Building with MATLAB

You can use MATLAB to generate a MEX-file. Type the following command in the Command Window:

cd src
make

You can build the MEX-file in Debug mode. Type the following command:

make debug

You can also build it in Unittest mode, to check the validity of sofamyroom functions. Type the following command:

make test

On Windows, pass the location of zlib as extra arguments, for example make('-IC:\vcpkg\installed\x64-windows\include', '-LC:\vcpkg\installed\x64-windows\lib', '-lzlib').

Known issues and limitations

  • When using the MEX library, MATLAB can crash since the memory allocation performed by libmysofa is not persistent.

  • The library is single-threaded and keeps the loaded sensors in global state: run one simulation at a time per process. To simulate many rooms in parallel, start several processes; the Python VAST generator does this for you with generate(..., workers=n).

  • Image sources are placed at integer sample delays (no fractional-delay interpolation).

  • room.surface.absorption is the energy absorption coefficient: each specular reflection multiplies the amplitude by sqrt(1 - absorption). room.surface.diffusion is the scattering coefficient: the specular image source is weighted by (1 - diffusion) and the diffuse part by diffusion, both in amplitude. The latter is the original Roomsim convention and is kept so that existing results can be reproduced; an energy-consistent weighting may be added later as an option. Both coefficients must be in [0, 1] (values above 1 found in some material tables have to be clipped by the user, the setup is rejected otherwise).

  • Reflections are positive real numbers and the analytical directivity patterns (cardioid, dipole, …) use the magnitude of the pattern only, so a dipole has two in-phase lobes. This is a simplification shared by the Roomsim family.

  • SOFA receivers must use the SimpleFreeFieldHRIR convention with exactly two receivers (ears).

  • The SOFA Data.Delay is ignored unless the receiver description contains delay=1, in which case it is applied as a whole-sample shift per ear.

  • The diffuse tail is rendered from six spatial directions.

Testing

The unit tests need the MIT KEMAR HRTF set in data/:

curl -L -o data/MIT_KEMAR_normal_pinna.sofa http://sofacoustics.org/data/database/mit/mit_kemar_normal_pinna.sofa

Then build with CMake and run ctest:

cmake -S src -B build/cmake -DCMAKE_BUILD_TYPE=Release
cmake --build build/cmake
ctest --test-dir build/cmake --output-on-failure

The Python package is tested with pytest (the SOFA file is downloaded automatically if missing; one test compares the Python output with the sofamyroom executable above, bit for bit, when it has been built):

pip install -e ".[tests]"
pytest

Building the Python package

pip install . (or pip install -e . for development) compiles the library through the same CMake project with -DSOFAMYROOM_PYTHON=ON; it needs a C compiler and the zlib development files, CMake and ninja are fetched automatically if they are not installed. python -m build produces the sdist and the wheel.

Building the documentation

The documentation is built with Sphinx only; the Python pages use autodoc, so the package must be installed:

pip install -e ".[docs]"
sphinx-build -b html src/docsrc/sphinx build/html

The site at robaru.github.io/sofamyroom is rebuilt from master by the docs GitHub workflow.

License

The code written for sofamyroom is licensed under the EUPL-1.2 (LICENSE.txt). The files inherited from Roomsim by Steven M. Schimmel (University of Zurich, 2009) keep their original GNU GPL-3.0-or-later licence, and our modifications to them are released under the same GPL terms. Each of these files carries the original Roomsim header followed by a notice that states whether, and how, it was changed for sofamyroom:

  • src/libroomsim/ (all .c and .h files, except include/global.h which is new and EUPL-1.2)

  • src/libroomsim.h, src/main.c, src/mexmain.c, src/unittest.c

  • data/materials.mat (the Roomsim absorption-coefficient database used by editabsorption.m)

  • matlab/ estimateRT60.m, editabsorption.m, plotabsorption.m, estimateroombreakfreq.m, plotcoordsystem.m, plotbrir.m, readsetup.m, rsound.m, yprTr2s.m, yprTs2r.m, selectabsorption.m, plotroom.m, setcomplexity.m

Since the simulator core is GPL, every compiled form of sofamyroom (command line tool, MEX file, or a package that links it) is a combined work distributed under the GNU GPL-3.0-or-later; the EUPL-1.2 permits this through its compatibility clause. The GPL text is in LICENSE-GPL-3.0.txt; the Python wheel declares EUPL-1.2 AND GPL-3.0-or-later and ships both texts.

The third-party code included in src/ (libmysofa, PocketFFT, SFMT) is listed with its licence texts in THIRD_PARTY_LICENSES.md.

Credits

References

[1] C. Gaultier, S. Kataria, and A. Deleforge. “VAST: The virtual acoustic space traveler dataset.” International Conference on Latent Variable Analysis and Signal Separation. Springer, Cham, 2017.