surface that breathes at the track's tempo
The design session with PLN, hands on the device, four AskUserQuestion answers
and three live iterations. Everything here is v3-only BY CONSTRUCTION: the
corpus, BootTidal, SC and Ardour still speak v2 absolutes, so the classic LCXL
(PLN's fallback, and his friend's surface) keeps working with zero changes —
"we need to be BC always" is the standing constraint.
THE LANGUAGE (lcxl3_language.py, new — parallel to lcxl-leds.py, replacing
nothing):
- rings: hue = ROLE (per-orbit family anchors, warm rhythm bloc / purple bass /
cool melodics), lightness = VALUE. This is the exact trade v2 could not make
with three LED hues — the settled 2026-07-29 language spent all hue on value
because role had nowhere else to live. RGB dissolves the trade.
- dark = unmapped survives unchanged: it outranks everything on both surfaces.
- DJF row C, PLN's spec after the first blue<->green attempt proved "too
subtle": blue = lows kept, DEEP GREEN BREATHING SLOWLY = the zero mark
(there is no pot ridge on an endless encoder — the 0 must be VISIBLE),
then green -> yellow -> red as the HPF cut grows. Near-silence extremes
breathe to the BEAT — sine, not blink ("a bit aggressive atm"), rate from
the track's setcps (118 BPM for rose_rouge). Wall-clock phase: it breathes
AT tempo without claiming to know Tidal's cycle position — true phase sync
is a feed from SC, later, not a silent assumption now.
DRIVER-OWNED TRUTH (three kinds, one principle):
- encoder VALUES: rows B/C relative, offset-64 decode — MEASURED off PLN's
slow clicks arriving as 63/65/66; the first decoder assumed two's complement
and read +1 as -63, direction inverted, every click a full-range jump. Row A
stays absolute deliberately: A1-A4 are Ardour-learned levels, and integrating
them from a blind seed would yank a live fader toward silence.
- row-E LATCHES: the latch never lived in Tidal (midiOn/midiOff read the last
value) — it lived in the v2 hardware's toggle buttons. v3 DAW buttons are
momentary, so the driver flips state on press, swallows the release, and the
LED paints driver state — which IS what Tidal hears. Row F stays momentary:
gestures are held, and the panic chord needs four simultaneous 127s.
- PAINT as a binding: the device repaints its own defaults on events we cannot
see, so the driver re-asserts the full board every 2 s — same doctrine as
every aconnect link on this rig. Faders are OUT of the paint path: they have
no LEDs, and painting them was a no-op lie this commit stops telling.
OLED:
- touched-control context in CORPUS terms, line 2 parsed from the .tidal:
"# crushbus", "mask <f f f t>", and — best of all — PLN's own inline stage
notes: ^35 shows "HANDS IN THE AIR", ^59 "Le Delay rose!!!", ^36 "Savoy 8/8
Break". His words, on his hardware, at the moment his finger lands.
- anti-blink: fields are diffed and the configure/bring-up pair fires only when
the overlay has likely expired — re-summoning a live overlay every event was
the blink PLN saw.
- gates read ON/off, DJFs read "LPF 43% / BYPASS / HPF 61% !!".
Validated on the live rig across three rounds of PLN's eyes and hands:
translation + paint + OLED coexist in one process; 27 live cells / 13 dark on
rose_rouge; 18/18 controls context-labelled; latch verified against E1.
| Name |
Last commit
|
Last update |
|---|---|---|
| .. | ||
| at | Loading commit data... | |
| bridge | Loading commit data... | |
| foundry | Loading commit data... | |
| pulsar-parvagues-hud | Loading commit data... | |
| pvlint | Loading commit data... | |
| tests | Loading commit data... | |
| README.md | Loading commit data... | |
| analyze_samples.py | Loading commit data... | |
| audio-lens.py | Loading commit data... | |
| bank-check.py | Loading commit data... | |
| button-column-audit.py | Loading commit data... | |
| button_roles.py | Loading commit data... | |
| cheat-sheet.py | Loading commit data... | |
| check-audio-graph.sh | Loading commit data... | |
| check-boot-blocks.py | Loading commit data... | |
| check-boot.sh | Loading commit data... | |
| check-drift.sh | Loading commit data... | |
| check-mix.py | Loading commit data... | |
| check-preload.sh | Loading commit data... | |
| check-tracks.sh | Loading commit data... | |
| control-lens.py | Loading commit data... | |
| deshadow-helpers.py | Loading commit data... | |
| fader-baseline.py | Loading commit data... | |
| fan_check.sh | Loading commit data... | |
| fix-button-roles.py | Loading commit data... | |
| fix-mute-roles.py | Loading commit data... | |
| gen_tokens.py | Loading commit data... | |
| gen_ts_types.py | Loading commit data... | |
| gig-log.py | Loading commit data... | |
| gig-log.service | Loading commit data... | |
| gig-metadata.py | Loading commit data... | |
| gig-up.sh | Loading commit data... | |
| gig_record.sh | Loading commit data... | |
| install-protect.sh | Loading commit data... | |
| lcxl-init.py | Loading commit data... | |
| lcxl-leds-watch.service | Loading commit data... | |
| lcxl-leds.py | Loading commit data... | |
| lcxl-path.py | Loading commit data... | |
| lcxl3-driver.py | Loading commit data... | |
| lcxl3.py | Loading commit data... | |
| lcxl3_language.py | Loading commit data... | |
| lcxl_grid.json | Loading commit data... | |
| lcxl_grid.py | Loading commit data... | |
| master-out.py | Loading commit data... | |
| midi-autoconnect.service | Loading commit data... | |
| midi-autoconnect.sh | Loading commit data... | |
| migrate-columns.py | Loading commit data... | |
| mock-lcxl.py | Loading commit data... | |
| mute.tidal | Loading commit data... | |
| orphan-orbits.py | Loading commit data... | |
| parvagues-protect.service | Loading commit data... | |
| parvagues-protect.sh | Loading commit data... | |
| parvagues-rig.target | Loading commit data... | |
| parvagues-samples.service | Loading commit data... | |
| parvagues-sc-watchdog.service | Loading commit data... | |
| probe-chain.py | Loading commit data... | |
| pvbanks.py | Loading commit data... | |
| rig-pulse.py | Loading commit data... | |
| rig_units.py | Loading commit data... | |
| sample-watcher.py | Loading commit data... | |
| sample_tfidf.py | Loading commit data... | |
| sc-watchdog.sh | Loading commit data... | |
| set-coherence.py | Loading commit data... | |
| setlist.py | Loading commit data... | |
| setlist_samples.py | Loading commit data... | |
| shipowiz.py | Loading commit data... | |
| silent-eval.py | Loading commit data... | |
| solo.tidal | Loading commit data... | |
| surface-columns.py | Loading commit data... | |
| take-lens.py | Loading commit data... | |
| take-master.py | Loading commit data... | |
| take-segments.py | Loading commit data... | |
| tempo-lens.py | Loading commit data... | |
| tidal-ardour-autoroute.service | Loading commit data... | |
| tidal-ardour-autoroute.sh | Loading commit data... | |
| tidal-remote.py | Loading commit data... | |
| tools.png | Loading commit data... | |
| unmute.tidal | Loading commit data... | |
| unsolo.tidal | Loading commit data... |