feat(lcxl3): the surface follows the track — and the tempo knob grew notches
The driver parsed its .tidal once, at launch, and never looked again. PLN said
it three ways in one session: "i see still ROSE_ROUGE in title", "why dont i
see the lcxl colors evolve as i map buttons on the new track", "probably this
will be an opp to confirm you read current file well". One bug, three faces.
FOLLOW. The editor has published the loaded track for a while
(~/.cache/parvagues/current-track, written by the HUD) and logs every
ctrl+enter (eval-events.jsonl). The driver needed no new channel — it needed to
read. It now polls both once a second: a different path is a track change
(remap, relabel all 32 targets, repaint, reset the lap clock), and a changed
mtime on the SAME path is a re-read, so mapping a button and saving lights the
board within a second. --no-follow pins the old behaviour.
CARRY POLICY, PLN's spec verbatim: "faders are real positions, but could we
reset the knobs to 'defaults' on all effects? and maybe teh DJFs stay across
tracks so i can do djf-and-fader-crossfaded-transitions". So DJFs carry (they
ARE the transition), effect knobs go to 0, faders are physical and untouched.
Two cells carry that he did not name, because the sound would have taught us
the hard way: the TEMPO knob (resetting it means the range floor — a 60->120
transition would slam back to 60 exactly when the new track lands) and every
button (emitting to a gate is the mutebomb; latches reset in the driver so the
LEDs stop lying, but nothing is sent).
LIVE TEMPO. sept1's idiom `# cps ((range 60 180 "^29")/60/4)` makes B1 the
clock — and it steered the tempo all last session while the OLED said "B1
unmapped", which is the whole argument for following the track: the sound was
right and every label lied. The BPM is now derived from the knob, and bar phase
is INTEGRATED rather than read off the wall clock, because `time.time() * bpm /
60` re-scales all of history whenever the tempo moves — the countdown would
have jumped precisely mid-transition, the one moment it is read.
THE MOVE. PLN: "start holding kick mute, move kick to the 120bpm position (i
used the center notch, now ill rely on OLED), drop kick mute at end of a bar".
So the screen becomes the notch: BPM not wire units, an arrow to the nearest
landmark that vanishes when he is on it, and — while a mute is held — the bar
countdown ("DROP kick / ~120 BPM >2"), with the ring breathing at the beat to
count it in. The bar is real, not guessed: `resetCycles` shares a block with
the patterns, so every ctrl+enter IS cycle 0 and the eval log is a phase anchor.
Plus software detents, since the v3 encoder has no ridge: a deliberate single
click that would cross a musical tempo lands ON it and holds for two more
clicks; fast sweeps pass through untouched. Two versions of that welded the
knob to the first notch it met (the closest STEP to a landmark sits just below
it, so stepping up re-crossed it and snapped back — measured, 24 consecutive
clicks stuck at 114.8 BPM); the fix tracks WHICH landmark holds us by identity
and releases only once the value has actually left it.
And the mute overlay finally reports the whole held SET ("MUTE x2 /
kick+percs", "all") instead of the last finger down.
Honesty notes: 60-180 over 128 steps is 0.94 BPM/step, so exactly 120 is not
reachable (step 63 -> 119.5, step 64 -> 120.4). The readout prints "~120" for
the closest step and a bare "120" only when it is exact. A track wanting true
round tempos can quantise in the pattern:
`# cps ((quantise 1 (range 60 180 "^29"))/60/4)` — then two steps both land on
120 and the detent is the music's, not the driver's.
Also closed by evidence rather than code: A1's label is correct ("d9 level
[ard]" — the grid puts d9-d12 on row A, faders carry d1-d8), so the suspected
off-by-one that sat on the board was never real.
Showing
Please
register
or
sign in
to comment