@maruaudio/dsp/acoustics/rir-builder turns image sources into a room impulse response, ported from pyroomacoustics' rir_builder.cpp. Each image, an arrival time and an amplitude, is added into the response as a Hann-windowed sinc read from a look-up table, so it lands at a fractional sample. The same table drives rirDelaySum and rirFractionalDelay. A zero-phase 10 Hz high-pass then reproduces scipy's sosfiltfilt of the order-2 Butterworth upstream applies to the response. Plain functions are upstream's double instantiation; *F32 forms emulate the float one compute_ism_rir calls.
Parameters
| Call | Accepts | Default |
|---|---|---|
initRirSincLut(fdl, lutGran) | fdl odd integer 1 to 255 taps; granularity integer 1 to 256 points per sample; otherwise valid = false | 81, 20 (DEFAULT_* in @maru/acoustics-physics) |
initRirHighPass(fs, fc) | Cutoff in Hz; RBJ high-pass, Q = 1/√2 | 10 Hz (DEFAULT_RIR_HPF_FC) |
Lifecycle
The two init* calls allocate and run the only sin and cos. rirBuilderAccumulate(rir, length, times, amplitudes, start, end, fs, lut) adds images [start, end); [0, k) then [k, n) equals [0, n) bit for bit. The high-pass runs in place with a nine-entry scratch: rirHighPassBegin → rirHighPassStep(maxWork) until 0, or rirHighPassZeroPhase at once.
When to use it
Assembling a simulated room response from image sources, or adding fractionally delayed copies of a signal, in ranges that spread across blocks.
Limits
- Single-threaded, and nothing throws: an image starting before sample 0 or running past the end, or a non-finite time, is counted in the return value, and only in-range taps are written. An invalid LUT counts every item. A fractional delay outside the table's reach writes a zero row and counts.
fsis truncated toward zero. At most 16,777,216 images or high-pass samples and 65,536 delay-sum taps.- The high-pass, f64 rather than
@maru/filters-biquad's f32, refuses a response no longer than its nine-sample pad and leaves it unchanged.