feat(binaural): reverb size and per-band decay, live up to Studio (S2-15) - #351
Merged
Conversation
mgth
force-pushed
the
feat/binaural-reverb-bands-size
branch
from
September 2, 2026 17:31
93d80fe to
ead64bf
Compare
S2-15. The late tail had one decay time for every band and one set of
line lengths. Two more handles shape it the way a room's tail is shaped:
- `reverb.size` (0.5–2) scales every delay line together, allocated for
the maximum: shorter lines make a small, dense room, longer ones a
sparser, larger one. The feedback gains are recomputed with the lengths
so the RT60 stays what was asked at any size, and a running network
stretches its lines at no more than 0.02 samples per sample — a
second-long ±2 % pitch drift rather than a splice (a fresh or cleared
network snaps).
- `reverb.rt60_low_ratio` and `reverb.rt60_high_ratio` (0.25–4): the
decay time below ~250 Hz and above ~4 kHz as ratios of the broadband
RT60. Each line's loop gain becomes the broadband value plus two
first-order shelves — trapezoidal one-poles, exact complements, so the
shelf reaches its band's gain (the `exp` one-pole reached ~60 % of it) —
whose gains are what the band's own RT60 adds to the broadband gain.
At a ratio of 1 both terms are exactly zero: the default tail is
arithmetically the one before the shelves existed. The fixed one-pole
wall damping stays underneath; the high ratio acts on top of it.
`Fdn::set_params` takes the `BinauralReverb` block. Wired through
config (`render.binaural.reverb.{size,rt60_low_ratio,rt60_high_ratio}`),
engine build, persistence, OSC (`…/reverb/size`, `…/reverb/rt60_low_ratio`,
`…/reverb/rt60_high_ratio`), the state snapshot, BINAURAL.md, and Studio:
three sliders in the Late reverb block (the ratios on log2 sliders so ×0.5
and ×2 sit symmetrically about ×1), three Tauri commands, i18n ×8.
Tests: first output of a fresh network lands after the pre-delay plus the
shortest line at each size and the decay slope is size-invariant; a size
change on a running network slews at the bound and gets there; bass ×4
lengthens the 40–150 Hz tail more than tenfold and treble ×¼ shortens the
4–8 kHz tail more than tenfold, each leaving the other band within 3 dB
(band energies off a Hann-windowed FFT).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
mgth
force-pushed
the
feat/binaural-reverb-bands-size
branch
from
September 2, 2026 17:37
ead64bf to
7cd413a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Series 2, lot 3, S2-15 — reverb size and per-band RT60, three settings wired from YAML to Studio.
reverb.size(0.5–2, default 1): scales every FDN delay line together (allocated for the maximum). Feedback gains follow the lengths so the RT60 is unchanged at any size. A running network stretches its lines at ≤ 0.02 samples/sample (a second-long ±2 % pitch drift, not a splice); a fresh or cleared network snaps.reverb.rt60_low_ratio/reverb.rt60_high_ratio(0.25–4, default 1): decay time below ~250 Hz / above ~4 kHz as ratios of the broadband RT60. Per line, the loop gain becomes the broadband value plus two first-order shelves (trapezoidal one-poles — exact complements; theexpform only reached ~60 % of the band's gain) carrying what the band's own RT60 adds. At ratio 1 both terms are exactly zero: the default tail is arithmetically unchanged. The fixed wall damping stays underneath.Wiring
live_params→config(render.binaural.reverb.{size,rt60_low_ratio,rt60_high_ratio}) →renderer_build→persist→osc_contract+osc(…/reverb/size,…/reverb/rt60_low_ratio,…/reverb/rt60_high_ratio) →snapshot(size,rt60LowRatio,rt60HighRatio) → BINAURAL.md (table, OSC table, a Tail character tip) → Studio: three sliders in the Late reverb block (ratios on log2 sliders), three Tauri commands, i18n ×8 (npm run i18n:check: parity).Tests
size_scales_the_lines_and_keeps_the_decay,size_changes_are_slewed,band_ratios_shape_the_decay_by_band(bass ×4 → >10× longer 40–150 Hz tail; treble ×¼ → >10× shorter 4–8 kHz tail; each leaves the other band within 3 dB; band energies off a Hann-windowed FFT).cargo test -p renderer --lib: 384 passed, 2 ignored.cargo test -p runtime_control: green (contract conformance included).cargo checkonorender_engineand Studio'ssrc-tauri: clean.npx vite build: OK. Golden unchanged.Listening
Size 0.5 vs 2 at the same RT60; bass ×1.5 + treble ×0.5 against a flat decay on dialogue and on a held note.
🤖 Generated with Claude Code