Replace the 14 sparse starter grids with 16 hand-authored arrangements
that use all 16 voices and evolve over the 32 bars via sections
(intro / build / drop / break / final) with fills and accents.
- Styles: techno_drive, acid_journey, trance_euphoria, psytrance_roll,
detroit_soul, industrial_grind, hardcore_punk, dub_techno, breakbeat,
minimal_hypno, ambient_intro, peak_drop, rave_stab, tribal_perc,
bass_science, melodic_builder.
- Every voice featured across the set (ride/rim/tom/reese/bells/sweep
now used, not empty); peak_drop activates the full kit on the drop.
- generate_presets.py reworked with a sections DSL; prints a voice-
coverage report (16/16).
Track last-applied color per voice in ~matLastColor; ~matApplyBar
skips Pdef re-source and re-play when color is unchanged and non-zero,
eliminating envelope re-attacks on sustaining pads/subs/reese/sweeps.
~matStop resets ~matLastColor to -1 so subsequent play re-applies all.
~matVariation now returns nil for color 0 instead of the base pattern.
loadMatState validates each cell is an integer 0..6.
Adds step 6i to data_only/boot.scd: loads matrix.scd after
sections.scd, matching the additive load pattern used by every
other data_only feature file.
Remove the try-catch wrapper added around s.waitForBoot in
sound_algo/engine.scd — it swallowed real boot errors in
production. Move boot-failure tolerance into
sound_algo/tests/test_tempo.scd instead, where it belongs.
data_only/engine.scd was not affected (no wrapper added).
Move ~lp[\clipGen] increment inside the four transitions that
schedule or cancel a closure (s==0 launch, s==3 cancel-stop,
s==1 stop, s==2 cancel-launch). No-op re-taps (s==1/2 on launch,
s==0/3 on stop) no longer clobber the pending generation counter.
Also clamp /launch/quant to clip(0.125, 64) instead of max(0.125)
to prevent a runaway large value from locking out launches.
~toscArmedPush now iterates all 16 pads plus melseq and rhythmseq,
sending 0/1/2/3 (off/playing/queued-launch/queued-stop) from clipState
with fallback to armed membership for concert-driven clips. Test
extended with clipState in dummy ~lp and clipState read assertion.
Add 4-state machine (off/playing/queued-launch/queued-stop) to ~lpArm.
Launch and stop are quantized to ~lp[\quant] beats (default 4) via
clock.schedAbs(clock.nextTimeOnGrid(q)). Per-clip generation counter
cancels superseded callbacks on re-tap. New env fields: ~lp[\quant],
~lp[\clipState], ~lp[\clipGen]. New /launch/quant OSCdef. ~lp[\armed]
semantics preserved so /launch/clear and concert logic keep working.
data-only boot does not load palette/scales.scd, so
~scaleMinorPent was nil and ~fpResolve crashed on wrapAt.
Embed fallback scale arrays so notes resolve headless.
Replace single ~tosc NetAddr with ~toscClients Dictionary
(keyed by ip) so feedback OSC reaches all connected clients
(web bridge + iPad) simultaneously. ~toscTouch deduplicates
by IP and logs only on first connection. ~toscSend iterates
the dictionary; no-op when empty.
Test: add assertion that two distinct IPs produce size==2.
Balance: P:0 B:0 on both files. Headless TEST PASS.
Add /control/fp (on/off/scale/inst/sens/octave/debug) so the
air-piano is controllable on a headless sclang, plus a debug
strike log gated by ~fpDebug.
Adds sound_algo/data_only/touchosc_feedback.scd: captures the
controlling client IP from inbound /launch* OSC traffic, pushes
/armed/<name> for all 16 pads, /sync/beat each beat on ~lp[clock],
/sync/rms at 20 Hz (server-only, guarded), and echoes
/seq/rhythm/state + /seq/melody/state on preset select. Additive,
nil-guarded, safe to load headless without a booted audio server.
Also adds test/test_touchosc_feedback.scd: headless harness that
builds a dummy ~lp env, loads the feature, asserts the three public
API functions are wired, exercises ~toscArmedPush with nil ~tosc,
and prints TEST PASS.
Wire finger_piano.scd into both data-only boot paths so
OSCdef /pose/finger and ~fp* API are available at runtime.
Call ~fpModTick on every /pose/hands frame (~30 Hz) for
continuous air-piano modulation. Document FINGER_PIANO env
vars in CLAUDE.md.