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
  • gig-log.py
Find file
BlameHistoryPermalink
  • PLN (Algolia)'s avatar
    feat(gig-log): log WHICH TRACK is loaded — the key that decodes the whole MIDI stream · d5baca32
    PLN recorded an afternoon of OPAL takes, then asked for "a master split per track
    loaded time". The answer should have been trivial. It was not: nothing in the rig
    recorded WHEN each track was loaded.
    
    The gig log had 78222 samples of thermals, xruns, gear and 7429 coalesced MIDI CC
    events for today alone — and no way to say what any of it was. A CC 41 is
    meaningless on its own, because the LCXL map is PER TRACK: on one track index 41 is
    a crush bus, on another it is a break gate. The performance data was all there and
    none of it was resolvable.
    
    Meanwhile the exact ground truth was sitting in a 33-byte file the whole time.
    Pulsar has published `~/.cache/parvagues/current-track` since #84 (2576e77) for the
    LED watcher to follow. Nobody was reading it into the log.
    
    WHY THIS MATTERS MORE THAN THE SPLIT IT WAS ASKED FOR
    
    Splitting a livecoded set by ear is genuinely hard, and we have the scars: orbit
    roles stay stable across tracks so level/presence detection fails, and every dN is a
    4-cycle crossfade that bleeds the incoming track into the outgoing one's tail — the
    existing Bandcamp splits carry that bleed. A `k:"track"` line replaces all of that
    inference with a timestamp. Boundaries stop being clever and become read.
    
    And it retro-actively upgrades the CC stream from telemetry to an annotated
    performance score: track + CC + time resolves, through the per-track LCXL map we
    already generate, to "d4's DJ filter opened at 18:42:13". That is the input for
    telling practice apart from performance (hands-off vs hands-on density), for finding
    the moment worth clipping, and eventually for the emotion/timeline bundle.
    
    IMPLEMENTATION — deliberately the boring version
    
    - `_read_track()` never raises: absent file (publisher not up yet) or a short read
      both degrade to None. A missing track must degrade the log, never stop it.
    - Written ONLY on change, so a 3-hour session costs a handful of lines instead of
      10800 repeats of one string. The header carries the initial value, so a session
      that never switches still has one authoritative statement of what was loaded.
    - Polled, not watched — for the same reason the LED watcher polls. One stat+read of
      33 bytes per second is unmeasurable; an inotify watch adds a dependency and a
      whole class of "the watch silently died", which is the exact failure mode this
      data exists to prevent.
    - `load()` folds track records into `marks` so they render in the existing timeline
      for free, keeping `k:"track"` so a splitter can tell an automatic boundary from a
      human annotation.
    
    VALIDATED
    - `selftest` PASS; sampler + both readers still 0.66% of one core over 6s, well
      under the 3% observer budget (the observer must not perturb — we already learned
      that lesson when probe-chain's own capture streams caused the xruns).
    - END-TO-END, not just unit: ran the real recorder against a temp track file, moved
      it twice, and read the log back. Header carried the initial track; both changes
      appeared exactly once with their `from`, each within the 1s poll. Green tests on a
      pure function would not have proven the value reaches the file.
    PLN (Algolia) authored Jul 29, 2026
    d5baca32
gig-log.py 63 KB
EditWeb IDE
×

Replace gig-log.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.