Skip to main content

shroom

Spherical Harmonics Room

A Python library for simulating room acoustics using Spherical Harmonics (Ambisonics). It provides tools for simulating room impulse responses (ARIR), microphone arrays, and binaural rendering.

Features

  • Room Simulation: Image Source Method (ISM) adapted for Spherical Harmonics.
  • Spatial Signals: Unified handling of Time, Frequency, Space, and Spherical Harmonics (SH) domains.
  • Processors: Modular processing chain including:
    • ArrayDecoder: Simulates spherical microphone arrays.
    • ASMEncoder: Encodes microphone signals to Ambisonics (ASM).
    • BinauralDecoder: Decodes Ambisonics to Binaural audio using HRTFs.
  • Rotation: Efficient rotation of sound fields and HRTFs using Wigner-D matrices, or via space domain grid rotation.
  • Visualization: 2D and 3D plotting of room geometry, sources, and receiver orientation.

Installation

The package is published on PyPI as pyshroom (not shroom). There are two install flavors:

1. Minimal — just the core library

pip install pyshroom

Installs shroom and its runtime dependencies (numpy, scipy, matplotlib, pyroomacoustics, sofar). This is all you need to simulate rooms, encode Ambisonics, and render binaural audio from your own scripts.

2. With shroom_dev — extras for examples and projects

pip install "pyshroom[dev]"

Installs everything above plus the companion package shroom_dev, which bundles helper modules used by the examples, tests, and research projects in this repo:

  • shroom_dev.plot — loglog_plot for error curves with variance bands.
  • shroom_dev.sound — play_audio helper around sounddevice.
  • shroom_dev.errors — the ASM/BSM evaluation metrics used by the projects/ scripts (asm_mse_error, asm_bin_mse_error, asm_bin_magnitude_mse_error, linear_spectral_error, bsm_mse_error, bsm_mag_mse_error).
  • shroom_dev.file_utils — extra file loaders.

The [dev] extra also pulls in pytest, black, sounddevice, and pyyaml.

Running from a git checkout

If you cloned the repo to hack on the library itself, install it editable:

git clone https://github.com/Yhonatangayer/shroom.git
cd shroom
pip install -e ".[dev]"

You can then run the example scripts under examples/ and the research scripts under projects/ directly — they import from shroom and shroom_dev.

Quick Start

Basic Binaural Rendering

import numpy as np
from shroom.acoustics.room import Room
from shroom.paths import DEFAULT_WAV_PATH

# 1. Initialize Room
room = Room(
    dimensions=[6.0, 5.0, 3.0],
    absorption=0.8,
    sh_order=3,
    fs=48000
)

# 2. Add Source and Receiver
room.add_source([4.0, 2.0, 1.5], signal=DEFAULT_WAV_PATH)
room.set_receiver([2.0, 2.0, 1.5])

# 3. Compute Ambisonics Response
amb_signal = room.compute_amb()

# 4. Plot
room.plot(plot_3d=True)

Dynamic Head Rotation

import numpy as np
from scipy.spatial.transform import Rotation
from shroom.acoustics.room import Room
from shroom.acoustics.processors import BinauralDecoder
from shroom.utils.file_utils import load_file
from shroom.paths import DEFAULT_HRTF_PATH, DEFAULT_WAV_PATH

# 1. Initialize Room & Compute Ambisonics (Reference Frame)
room = Room(dimensions=[6.0, 5.0, 3.0], sh_order=3, fs=48000)
room.add_source([4.0, 2.0, 1.5], signal=DEFAULT_WAV_PATH)
room.set_receiver([2.0, 2.0, 1.5])
amb_ref = room.compute_amb()

# 2. Load HRTF
hrtf_base = load_file(DEFAULT_HRTF_PATH)
hrtf_base.toSH(N_sp=3)

# 3. Rotate Listener Orientation (Modal Rotation via Wigner-D)
rot = Rotation.from_euler("zyx", [45, 0, 0], degrees=True)  # 45 deg Yaw
hrtf_rot = hrtf_base.copy()
hrtf_rot.rotate_sh_domain(rot)

# 4. Decode with Rotated HRTF
decoder = BinauralDecoder(hrtf_rot, sh_order=3)
binaural = decoder.process(amb_ref)

Complete ASM Processing Chain

from shroom.acoustics.processors import ProcessorChain, ArrayDecoder, ASMEncoder, BinauralDecoder
from shroom.encoders.asm import ASM

# 1. Setup Signal Chain: Room -> Array -> ASM Encoder -> Binaural Decoder
# Note: array_time_sh and asm_instance must be pre-configured
chain = ProcessorChain([
    ArrayDecoder(array_time_sh),  # Simulate mic recordings
    ASMEncoder(asm_instance),  # Encode mics to Ambisonics (ASM)
    BinauralDecoder(hrtf, sh_order=1)  # Render to binaural
])

# 2. Process Ambisonics through the Chain
binaural_output = chain.process(room.compute_amb())

Optimized Low-Order Rendering (MagLS)

from shroom.acoustics.hrtf_processing import magls_hrtf
from shroom.acoustics.processors import BinauralDecoder

# 1. Compute MagLS-optimized HRTF (Mitigates spectral artifacts at low SH orders)
hrtf_magls = magls_hrtf(original_hrtf, sh_order=1)

# 2. Decode using optimized modal weights
decoder = BinauralDecoder(hrtf_magls, sh_order=1)
binaural_output = decoder.process(room.compute_amb())

Dependencies

  • numpy
  • scipy
  • matplotlib
  • pyroomacoustics
  • soundfile
  • sounddevice
  • sofar

Paper and Citation

If you use shroom in your research, please cite our paper: SHroom: A Python Framework for Ambisonics Room Acoustics Simulation and Binaural Rendering

@misc{gayer2026shroompythonframeworkambisonics,
      title={SHroom: A Python Framework for Ambisonics Room Acoustics Simulation and Binaural Rendering}, 
      author={Yhonatan Gayer},
      year={2026},
      eprint={2603.27342},
      archivePrefix={arXiv},
      primaryClass={eess.AS},
      url={https://arxiv.org/abs/2603.27342}, 
}

Changelog

0.2.0

Three coupled changes. The first two are tied together (the pyroomacoustics upgrade is what forced the absorption fix); the third is an independent array-model fix.

1. pyroomacoustics ≥ 0.9 compatibility. The minimum supported version was raised from 0.7 to 0.9. Newer pyroomacoustics removed the deprecated absorption= kwarg in favour of materials=pra.Material(...), which is what motivated the change below.

2. BREAKING: absorption semantics fixed. The absorption coefficient is now applied directly as an energy absorption coefficient (e.g. absorption=0.8 → 0.8), matching materials=pra.Material(0.8).

Previously the value was forwarded to pyroomacoustics' deprecated absorption= kwarg, which silently converted it as 1 - (1 - a)**2 (so 0.8 became an effective 0.96) and emitted a DeprecationWarning. Simulated reverberation will therefore differ from shroom < 0.2.0.

To reproduce results generated with an earlier version, pass absorption_mode="legacy":

Room(dimensions=[6.0, 5.0, 3.0], absorption=0.8)                       # 0.80 (new default)
Room(dimensions=[6.0, 5.0, 3.0], absorption=0.8, absorption_mode="legacy")  # 0.96 (pre-0.2.0)

3. Spherical-array radial-function order mask removed (ghost-image fix). The per-order sigmoid mask 1 / (1 + exp(n − (ka+1))) was removed from the radial functions (shroom.acoustics.physics). Stacked across orders it formed a staircase of sharp spectral edges that rings in the time domain and is heard as a duplicate/ghost image for long radial filters (large duration ⇒ fine frequency resolution ⇒ ringing past the ~10 ms echo-fusion window). Damping is now only the smooth Wiener-style magnitude knee |b_n|² / (|b_n|² + limit²), which already suppressed the same numerically-insignificant coefficients without any order/frequency gate. The steering matrix — and therefore ASM and AA-MagLS encoder filters — differ from shroom < 0.2.0; the change removes the ghost image and moves the simulated array closer to true sphere physics. No API changes.

License

MIT License

Metadata

Release files for pyshroom 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyshroom 0.2.0
File Size Uploaded
pyshroom-0.2.0.tar.gz 2.8 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyshroom 0.2.0
File Interpreter ABI Platform
pyshroom-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 5.6 MB

Release files / pyshroom-0.2.0.tar.gz

Download URL pyshroom-0.2.0.tar.gz
Size 2.8 MB
Tags Source
SHA-256 checksum
How to use checksums
5d8ba014451cc52da2bb35dc28f98281e8e5dd407155a1f7560565f23d50a663
BLAKE2b-256 checksum
How to use checksums
33e4e9e1eccd78182e4104a13788fc9881240603ffa9acdfce6b6b7b91adff9a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.16

Release files / pyshroom-0.2.0-py3-none-any.whl

Download URL pyshroom-0.2.0-py3-none-any.whl
Size 2.8 MB
Tags Python 3
SHA-256 checksum
How to use checksums
2b9d427ce498977f21dea9cee3e1d56b6401b5f5f66da31c3670ecb63c904f47
BLAKE2b-256 checksum
How to use checksums
78171db0ace7b32403132ac7d4f1bc1c5d75c79f0350d528c654da2477307e80
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.16

Release history Release notifications | RSS feed

0.3.0

2 release files

0.2.2

2 release files

This release

0.2.0 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page