Skip to content

  • Projects
  • Groups
  • Snippets
  • Help
  • This project
    • Loading...
  • Sign in / Register
T
Tidal
  • Overview
    • Overview
    • Details
    • Activity
    • Cycle Analytics
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Charts
  • Issues 0
    • Issues 0
    • List
    • Board
    • Labels
    • Milestones
  • Merge Requests 0
    • Merge Requests 0
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
    • Charts
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Charts
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • PLN
  • Tidal
  • Repository

Switch branch/tag
  • Tidal
  • tools
  • lcxl3-driver.py
Find file
BlameHistoryPermalink
  • PLN (Algolia)'s avatar
    fix(lcxl3): identity is the ALSA port id, not the name — and the surface now plays · 9b482463
    Follow-up to fa22bb85, which fixed the direction trap but still could not run.
    Two more defects, then the first verified end-to-end translation.
    
    DEFECT 3 — the virtual port could never be found. _clients() returned
    (port_id, CLIENT_name) and every lookup matched the client name. python-rtmidi
    registers the client as 'RtMidiOut Client' and puts OUR chosen name on the
    PORT:
    
        client 133: 'RtMidiOut Client' [type=user,pid=...]
            0 'ParVagues LCXL3 '
    
    So `VIRTUAL_PORT_NAME in client_name` was false forever. The driver printed
    "reconcile: src=None dst=130:0 — nothing to do yet" on every cycle while
    `aconnect -i` listed the port plainly two lines below. _clients() now returns
    (port_id, client_name, port_name) and _find_port() matches either — both names
    are real and each is load-bearing somewhere.
    
    DEFECT 4 — prune() would have cut the driver's own link. It skipped "our" port
    by testing VIRTUAL_PORT_NAME against the name from `aconnect -l`, which is the
    CLIENT name — 'RtMidiOut Client'. That never matches, so the very first prune
    after a successful connect would have severed the connection it had just made,
    every cycle, forever. prune() now takes an explicit set of protected PORT IDS.
    Identity here is the ALSA port id; the names are decoration. Any place that
    matches a MIDI endpoint by name on this rig is a latent version of this bug.
    
    Also: reconcile() prunes only AFTER a confirmed connect. Cutting the raw
    surface while the replacement stream is not actually delivering would leave a
    dead surface, which is worse than a wrong one.
    
    VERIFIED END TO END on the live rig, PLN's hands on the hardware:
    
        fader 1      v3 #5   -> v2 #77   (38 events, full sweep 37..0)
        button E1    v3 #37  -> v2 #41   (127 then 0)
    
    ^77 is lcxl_grid's row D cell 1 and ^41 is the kick gate — the exact control
    the #94 migration aligned all 169 tracks onto, and the one v3 renumbering would
    have moved to button E5. 0 unmapped, 0 dropped. The graph after prune:
    
        133:0  RtMidiOut Client  -> 130:0    (ours, the only surface path)
        20:0 / 20:1 LCXL3 1                  GONE from SuperCollider
        14:0 Midi Through -> 130:2           re-cut every cycle
    
    Open, and deliberately not guessed at: something re-adds Midi Through -> SC
    within 5 s. midi-autoconnect only ever creates the OTHER direction, so the
    re-adder is unidentified. prune contains it each cycle; the window is real but
    small, and naming a culprit without evidence is how the last three "rig is
    broken" findings turned out to be the measuring tool.
    
    Resume point 1 is closed: the driver has met a live SuperCollider, and it took
    four defects to get one fader through. Every one of them was invisible to
    reading — three reported success while doing nothing.
    PLN (Algolia) authored Aug 29, 2026
    9b482463
lcxl3-driver.py 18.1 KB
EditWeb IDE
×

Replace lcxl3-driver.py

Attach a file by drag & drop or click to upload


Cancel
A new branch will be created in your fork and a new merge request will be started.