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
  • take-lens.py
Find file
BlameHistoryPermalink
  • PLN (Algolia)'s avatar
    feat(take-lens): pack a take so it travels with its performance — and fix the trim PLN caught · cc9cbf48
    Two things in one file, both from the same evening's practice recording.
    
    === PART 1: `pack` — the performance must travel with the audio (#106, #107)
    
    "ensure recordings have the midi too, keep this from blowing up tracking either
    ardour rec or compressing to avoid storing hours of no-move?"
    
    Today the audio is permanent and the performance is not. Ardour's sources live
    forever under the session; the MIDI and the track timeline sit in a gig-log
    directory that prune() deletes on a timer. So the 29862 CC events that explain
    take 94 were on a countdown while the audio they explain was not. `pack` writes a
    sidecar next to the audio: meta.json (window, sr, subtype, per-orbit peak dBFS,
    silent orbits, xrun delta, gear + boot state), midi.jsonl (every cc/note/track/mark
    record in the window, copied verbatim out of the log so pruning cannot reach it),
    and edl.json.
    
    The sidecar states its own honest limit in a field: gig-log COALESCES CC per
    (port, channel, controller) per second, keeping count + first/last/min/max. That is
    a faithful summary of a knob sweep and is what makes the log cheap, but a .mid
    rendered from it would be a reconstruction, not a recording. The JSONL is the truth.
    
    `--compress` then wavpacks every source and verifies each one with `wvunpack -vm`
    before reporting a single byte saved — an archiver that reports a ratio without
    checking is reporting a hope. The .wav is NEVER deleted; removal stays a separate
    human step after the take has been heard. FLAC was rejected outright: it cannot
    store 32-bit float, and routing through s32 would hard-clip the 8 orbits sitting
    over 0 dBFS while looking like a win on the silent one.
    
    Two measurement bugs found by running it on real data rather than trusting it:
     - xrun is a RUNNING TOTAL in gig-log's `s` records, not a per-tick delta (its own
       CUMULATIVE tuple exists for exactly this mistake). Summing it reported 58,668,469
       xruns for a 21-minute take. Rebased to last-minus-first: 230, a real number.
     - Records are not events. A `cc` record is a one-second bucket carrying `n`, so
       printing the record count understated the performance 25x (1167 vs 29862).
    
    === PART 2: the trim threshold was protecting every bad transition
    
    PLN heard the first machine-trimmed mix and found the hole: "silence around 18 is
    not normal its a bad transition ahah in a real mixing work wed cut it proper and
    fade or at least trim most". The gap he heard WAS detected and reported, and
    survived anyway. SILENT_RUN_S was 20 s; the three gaps that made it into the mix
    measured 17 s, 18 s and 11 s. Every one sat just under the bar. A threshold chosen
    so the trimmer could never eat a musical break had silently become a threshold that
    preserves every failed transition instead.
    
    Three changes, all of them his rule rather than a tuning:
    
    1. CLAMP, don't binary-cut. The bar drops to 10 s, but a detected silence is no
       longer removed whole — the last 2 s before the music resumes is kept as a
       breath. That is "or at least trim most" implemented literally, and it makes the
       lower threshold safe: the worst case if the rule fires on something musical is
       now a shortened rest, not a missing one. classify() computes both the detected
       region and the removed region so the report and the mixer cannot disagree.
    
    2. FADE every seam. Every cut this tool had ever made was a butt-join, which in a
       live room is a click. Each removal now fades out into the cut and back in out of
       it over 250 ms, applied sample-accurately — the old mixer decided keep/drop per
       one-second block by its midpoint, quantising every boundary to +-0.5 s.
       Verified on the re-rendered take: max sample-to-sample step at the five seams is
       0.0001-0.0029 against a p99.99 of 0.0562 for the take as a whole, i.e. the joins
       are 20-100x below ordinary musical transients.
    
    3. BRIDGE blips. A dead patch is rarely clean end to end, and one orbit's tail
       crossing -60 dBFS for a second splits it into pieces that each fall under the
       bar. Only single-orbit blips are bridged: a real hit lights several orbits, and
       that is what keeps this from swallowing a one-shot.
    
    Result on take 94: 143 s trimmed instead of 119 s, all five gaps closed including
    the one at +18.0 min he named, output 18.75 min, peak -3.36 dBFS.
    
    === `selftest`
    
    Added because two of these rules could not be validated on real material — the
    bridge fires zero times on take 94 and a correct fade is inaudible by construction.
    A rule you have never seen fire is a hope, not a rule. It found a bug on the first
    run, in the test's own arithmetic: asserting "no span survives a multi-orbit hit"
    was wrong because the left half is exactly SILENT_RUN_S long and qualifies by
    itself. The property that actually matters is that no trimmed span ever CONTAINS a
    moment when the music was playing, and that is what it now asserts.
    
    Correction to a verification, worth recording: the first check of the re-rendered
    mix reported an 11 s silence still present. It did not exist. I measured the output
    against -60 dBFS while the mix carries a uniform -16 dB, so I was testing at an
    effective -44 dBFS at source. At the matched threshold exactly one rest over 4 s
    remains, 9.25 s, correctly left alone as musical. The right lens per control, again.
    PLN (Algolia) authored Jul 29, 2026
    cc9cbf48
take-lens.py 47.5 KB
EditWeb IDE
×

Replace take-lens.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.