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
  • armada
  • tide-table
  • build_gig_tracksjson.py
Find file
BlameHistoryPermalink
  • PLN (Algolia)'s avatar
    feat(tide-table): tempo_timeline — check whether a planned track was played · 3ed1bc2d
    PLN's set plan lists WAP [133] second at CosmicFest and the recording has no WAP
    in it. He remembered dropping it — "didnt play WAP i think in the end [...]
    direct from Bombe DJ to Something about Drums, its what i chose that day" — and
    asked me to check rather than take his word, which is the right instinct: the
    rival explanation is that WAP IS in the recording, inside segment 1, and the
    boundary pass read two tracks as one. Duration cannot separate those (track 1 is
    6.8 min, an ordinary length here for one track and also for two short ones).
    
    Tempo can, because the two candidates differ: Bombe DJ is 124 and WAP is 133,
    which is 0.484 s against 0.451 s per beat — 7% apart, well inside what an
    inter-onset histogram resolves. So this walks a rendered track in windows and
    reports what tempo each window is actually playing, on the demucs DRUMS stem
    rather than the master, because the question is about kick timing and a stem is
    far cleaner to find onsets in than a stage-mic mix.
    
    Method deliberately copied from tools/tempo-lens.py, which measures a live orbit
    and cannot read a file: spectral-flux onsets, then the MODE of the inter-onset
    intervals — never the mean, which over a pattern with ghost notes lands between
    two real values and reports a tempo nothing is playing.
    
    Calibrated before it was trusted, on There's Something About Drums (declared
    160): median 161.5. Then the answer, on segment 1 with --expect 124 --alt 133:
    median 124.5 over 26 windows with a steady pulse, and NO window at 133 above the
    steadiness floor. One 20 s window reads 132.5 at confidence 0.11, below the
    floor and with no neighbour agreeing — WAP as a played track would occupy twelve
    to twenty-four consecutive windows, not one. So: not played. PLN's memory and
    the audio agree, and the boundary pass did not miss a track.
    
    Two bugs of my own on the way here, both worth the record:
    
      * the octave fold was an INFINITE LOOP. Folding into a band of [100, 180) by
        doubling-and-halving never terminates for a value like 99: 99 -> 198 (out
        the top) -> 99 -> 198, because no power of two lands it inside a band
        narrower than an octave. Two processes sat at 98% CPU while I assumed the
        machine was merely busy with the upload. The fold is now closed-form
        (`bpm * 2**-floor(log2(bpm/lo))`) into [X, 2X), and the CLI takes
        --octave-from because an octave is the only honest width: tempo from audio
        is determined up to a factor of two and no further.
      * the per-frame FFT loop was ~100k Python-level calls for a five-minute stem.
        One strided view and one batched rfft instead.
    
    Also, since the meta sidecar is where facts live: PLN's confirmed set time
    (~20:30), his verbatim approval of "Le Jardin", and the WAP question moved from
    open to resolved with both sources named. And build_gig_tracksjson now resolves
    the frontmatter-only fields (time, location, CTA, tags) BEFORE writing
    `_provenance`, so their origin is recorded in tracks.json whether or not
    --md-out was passed. tracks.json is the file that outlives the invocation.
    
    Side finding for PLN's ears, reported rather than acted on: over the last ~80 s
    of segment 1 the drums stem reads 161.5 BPM — the tempo of the NEXT track. Two
    readings, and I cannot choose between them from here. Either the segue is a long
    livecoded blend with Something About Drums layered in early (which is what
    "direct" looks like in TidalCycles), or the boundary at 6:46.6 sits later than
    the music does. His ear owns that one.
    PLN (Algolia) authored Sep 02, 2026
    3ed1bc2d
build_gig_tracksjson.py 11.1 KB
EditWeb IDE
×

Replace build_gig_tracksjson.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.