@maruaudio/dsp/acoustics/octave-bands splits a room response into octave bands with Antoni's orthogonal-like magnitude windows, ported from pyroomacoustics' AntoniOctaveFilterBank; the G_b² sum to one, so the weighted bands reconstruct the signal. Exact mode (offline) transforms each band's train once at n = nextpow2(2N), adds the G_b²-weighted spectra and inverts once. FIR mode (budgeted realtime) designs each band as a zero-phase T-tap FIR from G_b(T)² and applies it by FFT overlap-add over fixed blocks.
Parameters
| Call | Accepts | Default |
|---|---|---|
setOctaveBandLayout(layout, fs, base, overlap, slope) | Overlap 0 to 0.5; slope an integer 0 to 16; floor(log2(fs / base)) bands, 1 to 9 | base 125 Hz, overlap 0.5, slope 0 |
octaveFirTapsForRate(fs) | nextpow2(4096 · fs / 48000), clamped to 8 to 65,536 | 4096 at 44.1 and 48 kHz, 8192 at 96 kHz |
Centres are base · 2^b, edges f/√2 and f·√2; a bad layout returns a status and leaves 0 bands.
Lifecycle
Only create* allocates (FIR: powers of two, FFT 2 × taps to 131,072). Exact: createOctaveExactWeighting → beginOctaveExactWeighting → octaveExactAccumulateBand per band → octaveExactFinish. FIR: createOctaveFir → beginOctaveFirDesign → octaveFirDesignStep(maxBands) until octaveFirReady → octaveFirAccumulateBlock and octaveFirFlushBlock per block, or octaveFirApplyBand. Blocks per call never change the result.
When to use it
Applying per-band wall and air absorption to a simulated room response, or measuring one band by band.
Limits
- Exact mode takes at most 262,144 samples (2^19-point transforms); 9 bands.
- FIR mode drops the T/2 zero-phase delay; at T = 4096, 48 kHz it is −59.5 dB total relative L2 from exact mode.
- No third-octave layouts or minimum-phase synthesis; errors are status or boolean returns, never exceptions.