Skip to content

Library Comparisons

This page summarizes implementation-level differences between TorchRIR and related libraries within this comparison scope:

  • torchrir
  • gpuRIR
  • rir-generator
  • pyroomacoustics

Feature Comparison

Feature torchrir gpuRIR pyroomacoustics rir-generator
🎯 Dynamic Sources 🟡 Single moving source 🟡 Manual loop
🎤 Dynamic Microphones 🟡 Manual loop
🖥️ CPU
🧮 CUDA
🍎 MPS
📊 Scene Plot
🎞️ Dynamic Scene GIF 🟡 Manual animation script
🗂️ Dataset Build
🎛️ Signal Processing ❌ Scope out
🧱 Non-shoebox Geometry 🚧 Candidate
🌐 Geometric Acoustics 🚧 Candidate

Legend:

  • native support
  • 🟡 manual setup
  • 🚧 candidate (not yet implemented)
  • unavailable

Notes:

  • Signal Processing includes beamforming, DOA, BSS, adaptive filtering, STFT, and denoising.
  • For torchrir, this row is included for comparison only and is marked as scope out.

Visualization, Dynamic GIF, and Dataset Build (Source-Level)

Scoring criteria in this section:

  • Mark as when the functionality is provided as a library API/submodule (not only in examples).
  • Mark as 🟡 when possible only via manual composition without a dedicated library feature surface.
  • Mark as when no corresponding library functionality exists.

Visualization

Dynamic Scene GIF

Dataset Build

ISM High-Pass Filter (HPF) Implementations

This section focuses on libraries (in this comparison scope) that implement a built-in HPF for ISM-generated RIRs: torchrir, rir-generator, and pyroomacoustics.

torchrir: parameterization and equations

Defaults:

  • rir_hpf_enable=True
  • rir_hpf_fc=10.0 (Hz)
  • rir_hpf_kwargs={"n": 2, "rp": 5.0, "rs": 60.0, "type": "butter"}

For sampling frequency f_s and cutoff f_c, the normalized digital cutoff is:

\[ w_c = \frac{2f_c}{f_s} \]

Second-order sections are designed as:

\[ \mathrm{SOS} = \mathrm{iirfilter}\left( n,\; W_n=w_c,\; rp,\; rs,\; \text{btype}=\text{"highpass"},\; \text{ftype}=\mathrm{type},\; \text{output}=\text{"sos"} \right) \]

For each generated RIR tensor x, TorchRIR applies:

\[ y = \mathrm{sosfiltfilt}(\mathrm{SOS}, x) \]

along the time axis (last dimension), i.e. static (n_src, n_mic, nsample) and dynamic (T, n_src, n_mic, nsample) outputs are filtered in-place along nsample.

rir-generator: parameterization and equations

Default: hp_filter=True.

The filter coefficients are derived from sampling frequency f_s:

\[ W = \frac{2\pi f_c}{f_s} = \frac{2\pi \cdot 100}{f_s} \]
\[ R_1 = e^{-W}, \quad B_1 = 2R_1\cos(W), \quad B_2 = -R_1^2, \quad A_1 = -(1+R_1) \]

With input sample x[n], internal state v[n], and output y[n]:

\[ v[n] = x[n] + B_1 v[n-1] + B_2 v[n-2] \]
\[ y[n] = v[n] + A_1 v[n-1] + R_1 v[n-2] \]

State is initialized to zero (v[-1] = v[-2] = 0).

pyroomacoustics: parameterization and equations

Defaults:

  • rir_hpf_enable=True
  • rir_hpf_fc=10.0 (Hz)
  • rir_hpf_kwargs={"n": 2, "rp": 5.0, "rs": 60.0, "type": "butter"}

For sampling frequency f_s and cutoff f_c, the normalized digital cutoff is:

\[ w_c = \frac{2f_c}{f_s} \]

Second-order sections are designed as:

\[ \mathrm{SOS} = \mathrm{iirfilter}\left( n,\; W_n=w_c,\; rp,\; rs,\; \text{btype}=\text{"highpass"},\; \text{ftype}=\mathrm{type},\; \text{output}=\text{"sos"} \right) \]

For each generated RIR x, the library applies:

\[ y = \mathrm{sosfiltfilt}(\mathrm{SOS}, x) \]

This is forward-backward filtering (zero-phase response).

ISM Image-Source Amplitude Scaling

In ISM implementations, a common per-image gain form is:

\[ a_i \propto \frac{g_i}{d_i} \]

where g_i aggregates reflection/directivity terms and d_i is propagation distance. Some libraries additionally include free-field normalization by 4\pi:

\[ a_i \propto \frac{g_i}{4\pi d_i} \]

Quick comparison

Library Typical distance scaling Notes
torchrir 1/r Reflection/directivity gains are multiplied, then divided by distance.
gpuRIR 1/(4πr) CUDA core uses explicit factor in image-source amplitude.
rir-generator 1/(4πr) Core C++ implementation uses free-field normalization.
pyroomacoustics Usually 1/r in room ISM path build_rir_matrix uses 1/(4πr), so scale depends on API path.

Practical implication for cross-library tests

Even with matched geometry, beta, image limits, and interpolation settings, direct waveform-level comparisons can show an almost constant gain ratio near between 1/r and 1/(4πr) conventions. Normalize this global factor before enforcing strict amplitude-matching thresholds.

Known Differences

In addition to the scaling gap, the following implementation differences affect cross-library RIR waveform comparisons. Line references below were checked against:

  • torchrir (this repository, current branch)
  • gpuRIR (master snapshot used for this comparison)
  • pyroomacoustics 0.9.0
  • rir-generator 0.3.0

1) Image-source enumeration rules (max_order / nb_img)

  • torchrir: with max_order, it truncates by L1 norm (diamond); with nb_img, it enumerates a rectangular index range.
  • rir-generator: loops over a rectangular range, then filters by an order condition.
  • gpuRIR: maps nb_img directly to CUDA-side index expansion, so the enumeration path differs.

Practical note:

  • Even when parameters look identical, the included image-source set may not match exactly.

Source lines:

2) Fractional-delay interpolation kernel

  • torchrir: Hann-windowed sinc (default tap length 81), with selectable LUT on/off.
  • gpuRIR: Tw-based implementation with separate LUT and mixed-precision controls.
  • rir-generator: a different LP interpolation implementation (with different Tw definition).

Practical note:

  • Local waveform shape around sample positions can differ, causing mismatches in peak amplitude and fine temporal detail.

Source lines:

3) HPF implementation and defaults

  • torchrir: IIR HPF (enabled by default).
  • pyroomacoustics: also has HPF-enabled paths.
  • rir-generator: uses an Allen-Berkley style HPF.
  • gpuRIR: does not assume an equivalent built-in HPF path, and project discussion indicates the low-frequency attenuation behavior is an intentional design choice (not just a missing toggle).

Practical note:

  • HPF presence and coefficient differences change waveform and energy, especially in low-frequency bands.
  • In this repository, disabling HPF in torchrir for gpuRIR parity tests is only a comparison tactic. It does not imply that HPF should be disabled for normal ISM usage.

Source lines:

4) Late-reverb / diffuse-tail modeling

  • torchrir: can add a diffuse tail conditionally.
  • gpuRIR: also separates early reflections and diffuse components, but not with the same method.

Practical note:

  • If tmax or tail-related settings are not aligned, late-part waveform error can grow significantly.

Source lines:

5) Dynamic API assumptions

  • torchrir: explicitly models trajectories via simulate_dynamic_rir(src_traj, mic_traj, ...).
  • gpuRIR: designed around static RIR generation plus trajectory convolution; for fair comparison, fixed mic + single moving source is the cleanest setup.
  • rir-generator: no dynamic trajectory API (static-oriented).

Practical note:

  • Without matching scene constraints, a dynamic comparison may reflect API assumptions rather than core algorithm differences.

Source lines:

6) API-path differences inside pyroomacoustics

  • The main room ISM path typically uses 1/r.
  • The build_rir_matrix path uses 1/(4πr).

Practical note:

  • Even within one library, amplitude convention can vary by API path, so fix the call path during comparisons.

Source lines: