Commit b68e343e by PLN (Algolia)

gig: the double-press is real, and gig-log has been binding the feedback port

Two findings from one question. PLN asked whether a track change made him
press ^41 twice; it does, and carry_values() is explicit about why -- the
latch is cleared in the driver and no CC is sent, so SuperDirt keeps the old
127 while the driver believes the gate is shut. Press one re-sends 127 and
nothing moves. The driver's journal has the exact event at 00:38:41, two
latches cleared, ten seconds before love_first loaded.

The docstring's reason is the inverted part: it clears the latch 'so the LEDs
stop lying', but the gate is still open in SC after the change, so the lit
LED was the truth. Post-gig fix, because this is the mute path: carry the
latch for buttons the new track also maps, clear-and-emit-0 for the ones it
does not. Thursday's workaround is to close gates before switching, which
the journal already grades -- 0 latches cleared is a clean switch.

Verifying it from the MIDI log was impossible because there is none: 16227
sample records, 0 cc records, the tenth session running. find_seq_port
matches port names by substring, the driver publishes 'ParVagues LCXL3 ' and
'ParVagues LCXL3 FB' as a pair, and the resolver bound the FB input. Nothing
sends corpus CCs to an RtMidi input, so the reader subscribed and read
silence. The name was fixed in September; the direction never was.
parent eab26896
...@@ -670,3 +670,74 @@ process it had already been told was `Killed`. The launcher knows the PID and ...@@ -670,3 +670,74 @@ process it had already been told was `Killed`. The launcher knows the PID and
knows whether the spawn survived; it must say so. "A clean exit is not a launch" knows whether the spawn survived; it must say so. "A clean exit is not a launch"
is already written in `gig-up-window.sh` — this is the same lesson one layer in: is already written in `gig-up-window.sh` — this is the same lesson one layer in:
**a spawn is not a process.** **a spawn is not a process.**
## Thu 24, 00:40 — ^41 twice after a track change is REAL, and the MIDI log is dead again
**PLN was right.** Moving salut_nu → love_first he suspected the kick gate needed
two presses to respond. It does, and `carry_values()` says so on purpose:
```python
latches = sum(1 for on in self.latch.values() if on)
self.latch.clear()
for v2 in self.grid.BUTTON_CCS:
if v2 in self.values: self.values[v2] = 0
print(f"… {latches} latches cleared (no CC sent)")
```
Its own docstring: *"Emitting to a gate is the mutebomb; the latch state is reset
in the DRIVER so the LEDs stop lying and the next press means ON, but nothing is
sent."* So after the change the driver believes `^41` is off while **SuperDirt
still holds 127**. Press one toggles off→on and emits 127 — the value SC already
has, so nothing moves. Press two emits 0 and the sound finally follows.
Timestamped evidence of the mechanism firing on his exact switch:
`00:38:41 lap reset · 2 effect knobs -> 0 · 3 carried (DJF + tempo) · 2 latches
cleared (no CC sent)`, immediately before `00:38:51 track ~ love_first`.
The docstring's justification is the part that is backwards. It clears the latch
"so the LEDs stop lying" — but after the change the gate IS still open in SC, so
a lit LED is the **truth** and the dark one is the lie. The clear makes the LED
match the new track's *default* instead of the sound's *state*.
- [ ] **POST-GIG, not before** (this is the mute path — the worst thing to break
on a gig day). The fix the driver already has the information for: carry
the latch for buttons the NEW track also maps, and clear-**and-emit-0** for
the ones it does not. A gate nothing is listening to can be zeroed with no
mutebomb; a gate both tracks read keeps its state, so the LED and the sound
agree and one press closes it. `self.mapped` per track is the discriminator.
- **Thursday workaround: close your gates BEFORE you switch tracks.** Then the
clear is a no-op and there is nothing to double-press. The journal grades you
for free — `0 latches cleared` is a clean switch, `2 latches cleared` is two
gates you will have to press twice. Tonight's switches read 0, 0, 0, 2, 3, 3.
### And the reason this had to be read off the driver's journal: gig-log binds the FEEDBACK port
Zero `cc` records in `gig-20260923-103812.jsonl` — 16227 `s` samples, 28 `eval`,
9 `track`, and **0 `cc`**. That is the tenth session in a row with no MIDI. The
`mbind` line names the culprit:
```
"k":"mbind","p":"131:0","name":"ParVagues LCXL3","v3":false,"xlate":false (written 10:38:12)
```
The driver publishes a PAIR, and the two names differ by a suffix:
```
client 130: 'RtMidiOut Client' 0 'ParVagues LCXL3 ' <- the translated output (midiviz reads this)
client 131: 'RtMidiIn Client' 0 'ParVagues LCXL3 FB' <- the feedback input. gig-log bound THIS.
```
`find_seq_port` matches with `cand.lower() in line.lower()`, a **substring** test,
and `ParVagues LCXL3 FB` contains `ParVagues LCXL3`. So which of the two it binds
is decided by `aseqdump -l` ordering — a coin flip — and it lost. Nothing sends
corpus CCs to an RtMidi *input* port, so the reader subscribed successfully and
read silence, exactly the failure mode the comment above `SEQ_PREFERENCE` was
written to close. The name resolver was fixed; the *direction* was not.
- [ ] **One-line class fix** (safe — gig-log makes no sound): rank an EXACT name
match above a substring one, and exclude the pair's other half the same way
`HUI` is already excluded — `and " FB" not in line`. Then restart gig-log
and confirm within seconds of moving one knob that `cc` records appear.
**Verify by the records, never by the header**: `"midi": true` has been
lying for ten sessions because `available()` only asks whether aseqdump is
installed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment