Repository navigation
Hammerwork Grand and Skinwork Kit, physically modeled, plus shared state for voice machines - #23
Merged
Merged
Conversation
…contact, membrane modes (docs/41) kernels/10-physical: zoh-coefs/modal-step advance a damped mode exactly under a held force; contact-solve is the power-law Hunt-Crossley striker solved implicitly by Newton on the compliance equation; bessel.fy holds the circular membrane's first 40 modes, generated by tools/fit/bessel.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A state region is inline up to MAX_STATE; a machine declaring more, up to 16 KB, gets MAX_REGIONS heap regions of its own size at create. Every region access goes through stateRegion. Displays still read the first 2 KB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cs/41) grand: per key up to three stiff unison strings as mode banks, a felt hammer from Chaigne and Askenfelt's fits through the implicit contact, and a 12-mode soundboard plus a resistive dense-mode term behind a moving bridge; dampers and a live pedal. Measured against the CC0 VCSL Kawai. kit: Bessel-mode heads with tension glide, Hertz sticks and a felt beater, lumped snare wires that collide and buzz, and plates with a bounded cubic coupling and a diffuse-field wash; GM map, hat choke. Clean-room: from the cited literature and our own estimates only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… lockstep with the voices (docs/04) A voice machine can ask for one region for the whole machine (shared-size!) and a render word over it (shared!). The host renders the sounding voices for the declared period, then the shared word over the same samples, one voice at a time in voice order, so writes into the region land in a fixed order. The word wakes on note-on and sleeps once the voices are idle and its own output stays under the idle floor. Every entry word sees the region as ctx.shared. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s/04 §Shared state) - `offset voice-level!` names a voice state field that reports the voice's level; idling watches it besides the voice's own output, so a voice heard only through the shared word sleeps once both are quiet. - While the shared word runs, ctx.clock is its step's first sample, constant over the call, so an ifte on it is versioned and the untaken arm costs nothing. - MAX_STATE_BIG goes from 16 KB to 32 KB, still heap regions per voice. Fixture machines/raw_fixtures/shared_clock.fy and a test cover the clock across odd-length blocks and voice-level idling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-0.6) At HARD 0 the felt was hard enough to sound like a clavinet: an early spectral centroid of 1240-1380 Hz against about 900 Hz for the VCSL Kawai at mezzo velocity. At -0.6 it lands on the Kawai (821 / 801 / 1002 Hz at C3 / C4 / C5). The knob's range and mapping are unchanged. The presets voiced at the piano's own voicing (default, dry-studio, sustain-wash) move with it; felt-ballad goes to -1.0 to stay softer; bright-pop and honky-tonk keep their bright hammers. Goldens re-recorded, docs/20 regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nooga
force-pushed
the
claude/physical-piano-drums
branch
from
October 16, 2026 21:49
0ebd782 to
f368737
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.
Two clean-room physical models, the kernel layer under them, and host support for state that every voice of a machine acts on.
Machines (docs/41)
grand). Felt hammers strike up to three detuned stiff strings per key. The strings ring into a 12-mode soundboard through a moving bridge, with a resistive term for the board's dense upper modes. Velocity changes the tone through the hammer's nonlinear felt. Unisons give the two-stage decay, and PEDAL lifts the dampers. Six presets. The default hammer is now softer (HARD −0.6), which matches the VCSL Kawai's early spectral centroid at mezzo velocity: 821 / 801 / 1002 Hz at C3 / C4 / C5 against about 870–960 Hz. At HARD 0 it was 1240–1380 Hz and sounded like a clavinet.kit). Kick, snare with wires, side stick, three toms, closed / pedal / open hats, crash, ride and bell on the GM map. Five presets.kernels/10-physical: an exact modal step, implicit striker contact, and membrane modes.Host
shared-size!declares one region per machine, and"word" period shared!names its render word. Voices and that word step in lockstep, voices one at a time in voice order, so renders stay bit-exact at any thread count.voice-level!lets a voice heard only through the shared word report its own level for idle skipping.ctx.clockis the step's first sample, so anifteon it is versioned.The shared-state work was built for a port of frankensim's piano. That port was dropped: it costs about 4× more CPU than Hammerwork and sounded phased in listening. The host features stay because they are general.
Testing
zig build testpasses. New tests cover shared state ordering and idling, the shared-step clock across odd-length blocks, andvoice-level!.zig build bench -- --all --check --no-sheets: every machine with goldens is bit-exact. Grand's goldens are re-recorded for the new default. The command still exits 1 because shift2, resonator2, buffer2 and phaser2 came from master without golden files, which is unrelated to this branch.🤖 Generated with Claude Code