Add melseq (1 Pdef, 8 melodic sequences, /seq/melody) and rhythmseq
(3 sub-Pdefs rsk/rss/rsh, 8 16-step patterns, /seq/rhythm) to the
launchpad OSC bank. ~lpArm special-cases "rhythmseq" to arm/disarm
all three voices together. Web surface gets a Séquenceurs section
with arm pads, selector rows (.sel highlight), and vol sliders.
Add 10 OSCdefs to launchpad.scd: /control/harmony/{root,scale,octave,
phrase} mutate ~ccHarmony; /control/fx/{filter,stutter,crash,kick,swell,
breakdown} dispatch to ~ccMaster / ~ccFire. All nil-guarded; scale name
validated against ~ccScales. P:0 B:0.
Add lp_sub/acid/pluck/pad SynthDefs plus lpNote helper and six
pitched Pdefs (sub, acid, arp, lead, stab, pad) armable by name
via the existing /launch OSCdef.
Add launchpad.scd with 4 drum SynthDefs (kick/hat/clap/perc) and an
OSC-armable Pdef bank controlled via /launch, /launch/tempo,
/launch/clear. Patterns run on a dedicated TempoClock (~lp[\clock]).
Load it last in boot.scd, after concert_gestures.scd.
The 6 pitched concert morceaux now source their notes from the
global ~ccNote / ~ccHarmony instead of baked roots and scale arrays,
so the body's harmonic conducting drives their pitch. Each morceau
keeps its own rhythm, structure, SynthDefs and degree sequence; only
the pitch source changes. Acid line/storm gain a 4-entry phrase table
selected by ~ccHarmony[phrase]; hypno drift's drone base cutoff tracks
~ccHarmony[pad] brightness.
Register 5 body-gesture detectors (jump/stomp/squat/spin/tpose) in
sound_algo/data_only/concert_gestures.scd wired to ccFire/ccMaster FX
sinks. boot.scd loads the file after the morceaux block (step 6e).
Add concert_fx.scd providing ~ccMaster (filterTo/dip/stutterOn),
one-shot event synths cc_ev_crash/kick/swell, and ~ccFire helper.
Loaded in boot.scd after engine.scd so ~doFilter/~doMaster exist.
Add /pose/skel OSC route emitting nose, shoulders, hips,
knees and ankles (18 floats) from _emit_person. Add
\poseSkel OSCdef in data_feeds.scd storing the 9 joint
positions per pid; cleanup on \poseLeave.
At full-body concert distance MediaPipe cannot detect the hands
(/pose/hands all zero), muting every morceau hand mapping. ~ccPose now
fills pose[hands] from the body wrists (~poseWrist) when the hands are
not live, shaped exactly like ~handFeat (wrist height/x, arm spread ->
openness, per-tick wrist motion -> speed). All 8 morceaux are driven by
the arms at distance with NO per-morceau change (they read pose[hands]).
Verified headless.
The hand-based arms-crossed gesture could never fire: hand L/R is
position-sorted (rx>=lx always), and at full-body distance MediaPipe
doesnt detect the hands at all (crossing also occludes them). Detect
the advance from the body wrists instead: new /pose/wrist OSCdef ->
~poseWrist, and detectCross fires when the right wrist swaps clearly
left of the left wrist (a clear X), performer centered, wrists at chest
height. Verified headless (wrist-cross advance 1->2).
Add 07_dub_chords.scd: sustained sub (gated asr), dub chord
with CombL delay, deep kick on half notes. Register via
~concertAdd. Wire into boot.scd load list after 06_hard_rave.
Add 04_acid_storm.scd: overdriven 303 + hard kick + screech.
Right hand controls cutoff/res/drive; both arms high triggers
screech fill (once per raise). Registered in boot.scd load list.
inRange is not defined in the installed SuperCollider (Message not
understood) -> the arms-crossed detector errored at runtime and the
gesture never fired. Replace with explicit >= / <= comparisons.
Verified headless: the gesture now fires (advance/clamp logged).
Sequential techno setlist engine with crossed-arms gesture to advance
tracks. Adds ~poseCenter OSCdef, scene_concert.scd engine, morceaux/
directory, first morceau (Hypno Drift), and wires into boot/scenes.
The data-only boot started the \all scene (all data-web scenes). Boot
directly to \play (body-play) so a body-play session has no data-web
synths at startup. \all and the individual data scenes remain available
via /control/doScene <name>.
Final whole-branch review caught a cross-task defect: ~doScenePlay
started ~bpEngine but registered no cleanup, so ~doStopAll (run by
~doScene at every scene switch, and by \stop) never stopped the
engine -- body-play kept playing over any other scene, breaking the
"\stop coupe tout" contract. Register the stop via ~doRegisterPriv
(name, killFn) like every other scene. Verified on macm1: doScene(\play)
starts the engine, doScene(\stop) stops it.
- stop: call clock.stop + nil to prevent TempoClock leak per cycle
- remove unused ~doScene !? / ~bpRegisterPlay dead block
- clarify ~bpCtlDur comment: period is in beats, not seconds
The data-only boot opened the OSC receive port 57121 but fell back
silently to the lang port when it was busy — so /pose (data_only_viz)
and /data (data_feeds bridge), both sent to 57121, never reached
sclang and the patch looked alive but reacted to nothing. The port is
typically squatted by a zombie: a scsynth or data_feeds bridge launched
by a previous boot via unixCmd inherits the 57121 socket FD and outlives
its sclang parent, so a fresh boot can't bind it. Instead of falling
back, free the stale holder (lsof -ti UDP:57121 | xargs kill -9) and
retry openUDPPort. Verified: a planted zombie on 57121 is killed and the
port recovered on boot ("57121 recupere — sclang listening on 57121").
scene_pose_action's Routine died on its first tick with "Non Boolean in
test", killing the whole pose->FX mapping (base scenes still played).
Root cause in ~mapPoseToFx: `avgProbs.collect { _ / n }`. The underscore
inside an explicit { } block does NOT build {|x| x/n} — it builds a
function that RETURNS that function, so collect fills avgProbs with
Functions instead of numbers. The next line, avgProbs.maxIndex, then
compares Functions with `>` (a BinaryOpFunction) inside a boolean test
-> MustBeBooleanError. Replace with the idiomatic element-wise
`avgProbs / n`. Verified in isolation (headless sclang): ~mapPoseToFx
and ~mapHandsToFx now pass with both empty and populated pose dicts.
scsynth failed to boot under the data-only patch with "AudioDeviceStart
failed" because it opened a default input device that was unavailable
(an iPhone Continuity mic showed up in the device list) and needed a mic
TCC grant. The patch is output-only, so pin numInputBusChannels = 0; the
server now boots cleanly with no mic prompt.
Also nil-guard the hand-coordinate reads in scene_pose_action's hand->FX
map (hf[\lx]/\ly/\rx/\ry could be nil when one hand is absent, matching
the existing ? 0 pattern on lopen/rspeed/dist).
Note: a separate "Non Boolean in test" error still kills the
scene_pose_action routine on its first tick (pose->FX mapping not yet
live); ~poseKin/~poseState/~handFeat are Dictionaries populated by
data_feeds OSCdefs — left to investigate.
Add OSCdef(\poseHands) to data_feeds.scd storing lx/ly/lopen/lspeed,
rx/ry/ropen/rspeed/dist into ~handFeat Dictionary (9 floats, pid=0).
Initialize ~handFeat alongside existing ~poseState/~poseKin.
Load scene_pose_action.scd in boot.scd after scenes.scd so ~mapPoseToFx
is defined at runtime (was silently dead before).
Document /pose/hands contract in data_only_viz/README.md.
Restore 166 lines of feed implementations (VELIB Paris, SYTADIN
trafic Ile-de-France, HUB'EAU water, GCN seismic, GDELT events,
SWPC space weather, RTE eco2mix) that existed in the local canon
but were missing from origin/main after the 2026-05-13 cherry-pick
recovery cycle. Verified unique via diff against fresh clone.