Cross-voice coupling: a soundboard is one shared resonator below the voice sum, and the tap bus's delay may keep voices parallel #83

Closed
opened 2026-09-09 18:09:07 +00:00 by bcox · 1 comment
Owner

The voice-local tap bus (merged at 8422929) lets one layer read another's output inside a single voice. That gives string-into-body per note -- eight bodies for eight notes. It cannot give a soundboard, and no amount of per-voice coupling can: a piano has one soundboard, not one per key, and the reason an undamped piano blooms is that every string is loaded by every other string through shared wood. Eighty independent soundboards that never hear each other is a different instrument.

Same for a sitar's jawari, a set of sympathetic strings, and the resonant body of anything played polyphonically. It is the missing half of the physical-modelling story, and it is what the waveguide and modal engines were always heading toward.

Shape

The spec's own out-of-scope note sketches it: one shared resonator downstream of the voice sum, fed by a per-voice send -- which is also where a soundboard physically is. The send already exists as a specification: dsp/layer_strip.h's header names "a compressor and effect sends" as specified-but-unbuilt tenants, and this is the first thing that would actually need one.

The independence question, which is the whole design

Voices today are fully parallel -- that is what makes the pool parallel hardware in fabric, and it is the property most worth not spending. Naive sympathetic coupling destroys it: if voice B's output depends on the resonator, and the resonator depends on voice A, the voices serialize.

The bus's own delay discipline may be the way out, and this is the part worth testing first in design. The tap bus publishes one output sample late, uniformly, from a pending array -- which is precisely what makes routing cycles legal and slot order irrelevant. Applied here: each voice reads the shared resonator's previous output while contributing to the one being accumulated. Voices stay mutually independent within a sample; the only sequential element is the resonator itself, which is one instance clocked once per sample after the sum. In fabric that is one more pipeline stage, not a serialization of the pool.

If that holds, "breaks voice independence" -- the framing in the spec's out-of-scope note -- is true of the naive shape and not of this one. Worth proving before anything else, because it decides whether this is a contained feature or a restructuring.

Open questions

  • Scope of the resonator. One per patch, per channel, or global? Multitimbral makes this sharp rather than academic: sixty-four channels each wanting their own soundboard is sixty-four resonators, and sharing one across channels is musically wrong.
  • Feedback or feedforward. A resonator that only sums into the output is a reverb. Genuine sympathetic coupling returns energy to the strings, which is the expensive half and the half that actually blooms.
  • Which engine is the resonator. Modal is the natural fit -- a soundboard is a plate with modes, and dsp::ModeTable already generates them. A waveguide mesh is the other answer and costs far more.
  • What the send carries. Post-strip like the tap bus, or its own tap point; mono almost certainly, since a soundboard is not a stereo object.
  • Degradation. Voice count is already the binding constraint. A shared resonator is a fixed cost rather than a per-voice one, which is the good direction, but it still lands on the same budget.

Not a prerequisite

Nothing in the merged bus blocks on this, and this does not block on anything. It is a sibling feature that reuses the concept, not a stage of it.

Context: voice-local inter-layer routing merged at 8422929; see its design doc's Out of scope section.

The voice-local tap bus (merged at `8422929`) lets one layer read another's output inside a single voice. That gives string-into-body per note -- eight bodies for eight notes. It cannot give a soundboard, and no amount of per-voice coupling can: a piano has one soundboard, not one per key, and the reason an undamped piano blooms is that every string is loaded by every other string through shared wood. Eighty independent soundboards that never hear each other is a different instrument. Same for a sitar's jawari, a set of sympathetic strings, and the resonant body of anything played polyphonically. It is the missing half of the physical-modelling story, and it is what the waveguide and modal engines were always heading toward. ## Shape The spec's own out-of-scope note sketches it: **one shared resonator downstream of the voice sum, fed by a per-voice send** -- which is also where a soundboard physically is. The send already exists as a specification: `dsp/layer_strip.h`'s header names "a compressor and effect sends" as specified-but-unbuilt tenants, and this is the first thing that would actually need one. ## The independence question, which is the whole design Voices today are fully parallel -- that is what makes the pool parallel hardware in fabric, and it is the property most worth not spending. Naive sympathetic coupling destroys it: if voice B's output depends on the resonator, and the resonator depends on voice A, the voices serialize. **The bus's own delay discipline may be the way out, and this is the part worth testing first in design.** The tap bus publishes one output sample late, uniformly, from a pending array -- which is precisely what makes routing cycles legal and slot order irrelevant. Applied here: each voice reads the shared resonator's *previous* output while contributing to the one being accumulated. Voices stay mutually independent within a sample; the only sequential element is the resonator itself, which is one instance clocked once per sample after the sum. In fabric that is one more pipeline stage, not a serialization of the pool. If that holds, "breaks voice independence" -- the framing in the spec's out-of-scope note -- is true of the naive shape and not of this one. Worth proving before anything else, because it decides whether this is a contained feature or a restructuring. ## Open questions - **Scope of the resonator.** One per patch, per channel, or global? Multitimbral makes this sharp rather than academic: sixty-four channels each wanting their own soundboard is sixty-four resonators, and sharing one across channels is musically wrong. - **Feedback or feedforward.** A resonator that only sums into the output is a reverb. Genuine sympathetic coupling returns energy to the strings, which is the expensive half and the half that actually blooms. - **Which engine is the resonator.** Modal is the natural fit -- a soundboard is a plate with modes, and `dsp::ModeTable` already generates them. A waveguide mesh is the other answer and costs far more. - **What the send carries.** Post-strip like the tap bus, or its own tap point; mono almost certainly, since a soundboard is not a stereo object. - **Degradation.** Voice count is already the binding constraint. A shared resonator is a fixed cost rather than a per-voice one, which is the good direction, but it still lands on the same budget. ## Not a prerequisite Nothing in the merged bus blocks on this, and this does not block on anything. It is a sibling feature that reuses the concept, not a stage of it. Context: voice-local inter-layer routing merged at 8422929; see its design doc's Out of scope section.
Author
Owner

Closing with branch passive-bridge (b83d12f, 52 commits off 6858004, not yet merged).

What ships. The bloom is the damper-pedal patch: a played string and six sympathetic strings (C2, G2, C3, G3, C4, G4) driven from it, every string DC-blocked, every damper on the loop's loss gain, lifted by the key or the pedal (macro 1). It is a pedal-lifted reservoir on a drive, not energy crossing a bridge. sympathetic-strings and soundboard are unchanged in sound; the soundboard gains a tuning test.

What is in the engine. The passive string-to-board junction (waveguide bridge_tap; modal strings_tap, strings_amount, strings_mask), passive by construction and lane-green, plus a waveguide kLoss matrix destination, an optional output DC block at f0/8, and format minor 11. No factory patch is bridged.

Why not. Measured on the soundboard: the board's site feedthrough is 15.23, so the R 0.02 the first retune shipped was a near-matched bridge, taking 71% of a string's energy per lap; the plate's (2,2) mode sat on C4 at twelve seconds; and a mode's resonant admittance is about w^2 * tau * fs / 2, forty-odd times the feedthrough even for a quarter-second board. A partial within a few bandwidths of any of a 64-mode plate's modes is drained and pulled at any coupling that leaves the rest of the chord in tune. A real board has modal overlap of one or more; 64 modes cannot give that at any decay that rings. The junction stays for a board that can.

Details: docs/superpowers/ledgers/2026-09-23-passive-bridge-ledger.md and the spec's "Second pass" > "Outcome". Follow-ups: #100 (self-taps), #101 (sympathetic-strings DC), #102 (modal page id sweep), #103 (CC 64).

Closing with branch `passive-bridge` (b83d12f, 52 commits off 6858004, not yet merged). **What ships.** The bloom is the `damper-pedal` patch: a played string and six sympathetic strings (C2, G2, C3, G3, C4, G4) driven from it, every string DC-blocked, every damper on the loop's loss gain, lifted by the key or the pedal (macro 1). It is a pedal-lifted reservoir on a drive, not energy crossing a bridge. `sympathetic-strings` and `soundboard` are unchanged in sound; the soundboard gains a tuning test. **What is in the engine.** The passive string-to-board junction (waveguide `bridge_tap`; modal `strings_tap`, `strings_amount`, `strings_mask`), passive by construction and lane-green, plus a waveguide `kLoss` matrix destination, an optional output DC block at f0/8, and format minor 11. No factory patch is bridged. **Why not.** Measured on the soundboard: the board's site feedthrough is 15.23, so the R 0.02 the first retune shipped was a near-matched bridge, taking 71% of a string's energy per lap; the plate's (2,2) mode sat on C4 at twelve seconds; and a mode's resonant admittance is about w^2 * tau * fs / 2, forty-odd times the feedthrough even for a quarter-second board. A partial within a few bandwidths of any of a 64-mode plate's modes is drained and pulled at any coupling that leaves the rest of the chord in tune. A real board has modal overlap of one or more; 64 modes cannot give that at any decay that rings. The junction stays for a board that can. Details: `docs/superpowers/ledgers/2026-09-23-passive-bridge-ledger.md` and the spec's "Second pass" > "Outcome". Follow-ups: #100 (self-taps), #101 (sympathetic-strings DC), #102 (modal page id sweep), #103 (CC 64).
bcox closed this issue 2026-09-24 12:50:14 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
bcox/tymbal#83
No description provided.