Hi-hat self-oscillates and never retires its voice when the pedal is held closed #58
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
bcox/tymbal#58
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
patches/hihat.hdoes not decay when its pedal is held closed. Past amacro value of about 0.78 it converges to a self-sustaining limit cycle and
the voice is never retired, which is a permanently stuck voice in the plugin
rather than only an ugly tail.
Pre-existing — present since the patch was written, and not caused by the
modal-cymbalswork that found it.What it does
Pedal held closed, 0.1 s RMS of the shipped patch:
Rendered past the registry's own 2.5 s, it flattens at RMS 0.261 (-11.7 dBFS)
and holds that from 3 s out to 11.5 s — measured to 11.5 s because that is
where the render stopped, not because it stops. Spectrally it is two
near-sinusoids at about 4210 Hz and 5058 Hz plus their sum at 9265 Hz, which
is the felt's
|x|^2.5intermodulating with itself.Why it reaches the host
ModalLayer::IsActive()iscount_ > 0 && (!loop_.IsRetired() || flush_ > 0)and a sustaining loop never retires, so
ActiveVoices()never returns tozero for that note. The voice is held for as long as the pedal is down.
Where the edge is
Drive about 0.39-0.41, not the 0.5 that
patches/hihat.h's own header claims("fully pressed lands drive at 0.5, the measured edge"). The macro's authored
travel reaches 0.5, so roughly the top fifth of the pedal is across the
crossing. It is a threshold, not a gradient:
Why no test or audition has shown it
Bank.TheHihatPedalIsAPressAndNotAGatedoes hold the pedal closed, so thearticulation is exercised. Its late window is 0.40-0.57 s, on the descending
slope of the curve above (0.042 falling to 0.028; the minimum is about 0.0216
at 0.70 s), and it closes before the climb begins. The 2.5 s audition render
ends while the growth is still under the attack's own peak. The instability
falls outside both windows.
It surfaced only because
amplitude_tiltmade it worse enough to break thechoke test, and chasing that meant rendering held-closed for 12 s for the
first time in this repo.
Verification
Measured twice independently, the second time against
main's ownpatches/hihat.hcontent with no branch code involved.Related, and probably part of the same fix
patches/hihat.hdeclareslow_key = 0and clips low: 1388 samples on theSamplerail when rendered at its own declaredlow_key. Thecrashpatchadded on
modal-cymbalshad the same shape and was given a measured range(53-72) instead.
What a fix touches
Site 1's
force(0.1875) and the pedal's drive ceiling. Both are measurednumbers that
patches/hihat.h's header defends at length, and moving themchanges
Bank.TheHihatPedalIsAPressAndNotAGate's three ratios and everyhi-hat render in the bank.
A useful starting point exists:
patches/crash.hauthored the same feltmechanism from a fresh held-closed grid and found the loop's stability bound
to be
force * drive^1.5 ~= 0.049, which holds to 1% across an 8x range offorce and predicts this patch's own crossing at 0.0483. The shipped hi-hat
sits at 0.0663, about 1.37x over. That bound is recorded in
docs/superpowers/specs/2026-08-31-modal-synthesis-design.md.Settling this is also what unblocks
MaterialSpec::amplitude_tilton thispatch: the tilt was withdrawn from the hi-hat on
modal-cymbalsbecause itbreaks the choke test at sixteen times below its recommended value, and it
cannot return until site 1 is re-authored.
Recorded in
patches/hihat.h(header),patches/crash.h(choke section),docs/superpowers/specs/2026-09-04-modal-cymbals-design.md, anddocs/superpowers/specs/2026-08-31-modal-synthesis-design.md.