-
feat(lcxl3): the surface follows the track — and the tempo knob grew notches · 7c297a61
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.PLN (Algolia) authored7c297a61
×