Commit 59f6a20a by PLN (Algolia)

master Take103 (AI ENGINEER set) and Take104 (Rose Rouge club mix)

parent 084e692b
---
log: n/a
title: "Take103 (AI ENGINEER set) + Take104 (Rose Rouge club mix) exported and mastered"
date: 2026-09-26
task: n/a
tags: [mastering, postprod, tooling]
shareable: true
---
Both takes from `Tidal Live` exported straight from the Ardour capture files —
no Ardour export pass needed: the interchange `%L/%R` mono pairs were joined
into 12 stereo orbit stems with ffmpeg (`join=inputs=2`), then the
`tidal-ears master` chain (analyze → gain-trim → HPF/LPF → sum → glue comp →
two-pass loudnorm) rendered four masters in
`~/Work/Sound/Prod/AIEngineer2026_master/`:
- `AIEngineer2026_set_streaming.flac` — **-14.0 LUFS** on target, LRA 8.4
- `AIEngineer2026_set_club.flac` — -11.5 (single loudnorm can't reach -9
against the -1 dBTP ceiling; staged chain is the v2 item)
- `RoseRouge_clubmix_take104_{streaming,club}.flac` — -13.9 / -10.7
- `tracks_bandcamp/` — 13 per-track FLACs split with segments authored from
the gig-log track-switch timeline (second-precision), titled and dated
"AI Engineer, 2026-09-24 (live)".
Honest edges: rec joined *piment_bresilien* 3 min in (take is 76 min, set was
~95); **d8 was never armed at the gig** (the "Arm Tidal 08" fix happened the
next day), so Take103 has 11 stems; d9 is digitally silent for the whole Rose
Rouge take. The track switch log in `gig-20260924-005926.jsonl` proved to be a
better boundary source than silence detection — instant transitions leave no
gaps to find.
Found and fixed in tidal-ears (`3bafd03`): `split --segments` formatted the
slug key as `%02d` and crashed; play-order numbering is now the enumerate
index. 76 tests pass.
**Shareable bit:** the Ardour capture directory is already the export — mono
L/R pairs + a JSON timeline of what was played, and the master is two ffmpeg
passes away. The "export from the DAW" step is optional when the DAW never
stopped recording.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
{ {
"date": "2026-09-17", "date": "2026-09-17",
"task": "GUI launcher did not spawn the MIDI lens or the tray", "task": "GUI launcher did not spawn the MIDI lens or the tray",
"learning": "The launcher (gig-up.sh) and the unit converger (rig_units.py --ensure) disagreed on SuperDirt topology — raw sclang vs parvagues-sc.service — so the launcher never called ensure; the fix is ensure()'s proof-process skip, not another hand-copied unit list." "learning": "The launcher (gig-up.sh) and the unit converger (rig_units.py --ensure) disagreed on SuperDirt topology \u2014 raw sclang vs parvagues-sc.service \u2014 so the launcher never called ensure; the fix is ensure()'s proof-process skip, not another hand-copied unit list."
}, },
{ {
"date": "2026-09-17", "date": "2026-09-17",
...@@ -12,16 +12,16 @@ ...@@ -12,16 +12,16 @@
{ {
"date": "2026-09-18", "date": "2026-09-18",
"task": "tray GIG UP did nothing + midimon silent", "task": "tray GIG UP did nothing + midimon silent",
"learning": "The Bridge ran 'gig-up.sh --converge --quiet' but gig-up.sh's arg guard only knew --headphones/--help, so every tray GIG UP died on flag 1 (exit 2, output captured). Flags now parsed: --converge boots SuperDirt + converges units with NO app windows, --quiet mutes ok/info. midimon watches 132:0 (the lcxl3-driver's translated virtual port), not the raw surface — silence there just means the driver had no input yet." "learning": "The Bridge ran 'gig-up.sh --converge --quiet' but gig-up.sh's arg guard only knew --headphones/--help, so every tray GIG UP died on flag 1 (exit 2, output captured). Flags now parsed: --converge boots SuperDirt + converges units with NO app windows, --quiet mutes ok/info. midimon watches 132:0 (the lcxl3-driver's translated virtual port), not the raw surface \u2014 silence there just means the driver had no input yet."
}, },
{ {
"learning": "Two gig-up.sh exist: root (1-click, owns leds()) and tools/ (the GO/NO-GO gate the Bridge calls, where lcxl3-driver is boot=manual so nobody starts it). The v3 LCXL3 enumerates as 'LCXL3 1', breaking every v2 'Launch Control XL' grep — present/LEDs/path checks all silently misread. lcxl-path must match the driver's virtual PORT name 'ParVagues LCXL3' (under RtMidiOut client), never chase the PipeWire relay mesh (everything reaches everything via 143)." "learning": "Two gig-up.sh exist: root (1-click, owns leds()) and tools/ (the GO/NO-GO gate the Bridge calls, where lcxl3-driver is boot=manual so nobody starts it). The v3 LCXL3 enumerates as 'LCXL3 1', breaking every v2 'Launch Control XL' grep \u2014 present/LEDs/path checks all silently misread. lcxl-path must match the driver's virtual PORT name 'ParVagues LCXL3' (under RtMidiOut client), never chase the PipeWire relay mesh (everything reaches everything via 143)."
}, },
{ {
"learning": "WirePlumber 0.4.17 ignores wireplumber.conf.d SPA-JSON rules (0.5 syntax) — this box reads Lua from main.lua.d only, and a partial alsa_monitor.rules reassignment clobbers the built-in table by index (dropped the card to profile off). Every wireplumber restart tears down Ardour's JACK client; recovery needed a full Ardour relaunch. pactl/wireplumber restart restored the missing HiFi profile after a UCM probe failure (card showed only off/pro-audio)." "learning": "WirePlumber 0.4.17 ignores wireplumber.conf.d SPA-JSON rules (0.5 syntax) \u2014 this box reads Lua from main.lua.d only, and a partial alsa_monitor.rules reassignment clobbers the built-in table by index (dropped the card to profile off). Every wireplumber restart tears down Ardour's JACK client; recovery needed a full Ardour relaunch. pactl/wireplumber restart restored the missing HiFi profile after a UCM probe failure (card showed only off/pro-audio)."
}, },
{ {
"learning": "A generated boot file is only as good as the list it is generated FROM. gig-up.sh rewrote preload.scd on every launch from a default naming the PREVIOUS gig (setlist_opal2026.txt): measured 132 banks -> 45, leaving 41 of Thursday's banks to be read off disk mid-set — the exact 'crackle at the venue' failure the check was built for, re-armed by a stale default. Two structural lessons. (1) Name the set ONCE and have every consumer read that; the plan generator and the gate disagreeing about 'the set' is the whole bug. (2) An unconditional write is destructive in the quiet direction: the plan in place was a deliberate 132-bank UNION and regeneration could only narrow it, so gen_preload now asks check-preload first and leaves a covering plan alone. Corollary from the same pass: merging two tools that share a name means diffing what they DO, not just what they check — the root launcher span raw sclang while the other started parvagues-sc.service, so repointing the Bridge at 'one launcher' would have silently taken it off systemd (losing rlimits, the journal, supervision and OOM protection)." "learning": "A generated boot file is only as good as the list it is generated FROM. gig-up.sh rewrote preload.scd on every launch from a default naming the PREVIOUS gig (setlist_opal2026.txt): measured 132 banks -> 45, leaving 41 of Thursday's banks to be read off disk mid-set \u2014 the exact 'crackle at the venue' failure the check was built for, re-armed by a stale default. Two structural lessons. (1) Name the set ONCE and have every consumer read that; the plan generator and the gate disagreeing about 'the set' is the whole bug. (2) An unconditional write is destructive in the quiet direction: the plan in place was a deliberate 132-bank UNION and regeneration could only narrow it, so gen_preload now asks check-preload first and leaves a covering plan alone. Corollary from the same pass: merging two tools that share a name means diffing what they DO, not just what they check \u2014 the root launcher span raw sclang while the other started parvagues-sc.service, so repointing the Bridge at 'one launcher' would have silently taken it off systemd (losing rlimits, the journal, supervision and OOM protection)."
}, },
{ {
"learning": "A launcher's exit code cannot tell 'it worked' from 'it did nothing'. gig-up.sh --help prints its usage and exits 0, and the window wrapper closed on that zero exactly as it closes on a good launch -- so the rig had never once been started from the icon, and the only evidence was the LCXL staying dark. The log had been written faithfully all along and held nothing but the usage text. Structural lesson: for any wrapper that closes on success, the success test must be a POSITIVE marker the wrapped thing prints on its real path ('gig-up done'), never the absence of an error. And hold the coupling from both ends in tests, because the day someone rewords that last line, every real launch starts reporting a failure." "learning": "A launcher's exit code cannot tell 'it worked' from 'it did nothing'. gig-up.sh --help prints its usage and exits 0, and the window wrapper closed on that zero exactly as it closes on a good launch -- so the rig had never once been started from the icon, and the only evidence was the LCXL staying dark. The log had been written faithfully all along and held nothing but the usage text. Structural lesson: for any wrapper that closes on success, the success test must be a POSITIVE marker the wrapped thing prints on its real path ('gig-up done'), never the absence of an error. And hold the coupling from both ends in tests, because the day someone rewords that last line, every real launch starts reporting a failure."
...@@ -60,11 +60,22 @@ ...@@ -60,11 +60,22 @@
{ {
"date": "2026-09-24", "date": "2026-09-24",
"task": "midiviz: Tidal HL feed + ParVagues wave backdrop, column glow slowed 30%", "task": "midiviz: Tidal HL feed + ParVagues wave backdrop, column glow slowed 30%",
"learning": "Tidal already ships 4 OSC targets in BootTidal.hs — mirroring superdirtShape to a 5th port (oscfeed.VIZ_PORT 57130) gives the HL trigger feed without touching SuperDirt's port; and an OSC name/value fold must compare str(k+1) keys, not int, or every named arg silently vanishes." "learning": "Tidal already ships 4 OSC targets in BootTidal.hs \u2014 mirroring superdirtShape to a 5th port (oscfeed.VIZ_PORT 57130) gives the HL trigger feed without touching SuperDirt's port; and an OSC name/value fold must compare str(k+1) keys, not int, or every named arg silently vanishes."
}, },
{ {
"date": "2026-09-24", "date": "2026-09-24",
"task": "HL feed wired end-to-end; wordmark, single-instance, tray-via-systemctl", "task": "HL feed wired end-to-end; wordmark, single-instance, tray-via-systemctl",
"learning": "Tidal 1.9 addresses superdirtShape packets /dirt/play, not /play — captured off the wire, the documented address silently dropped every real packet while every synthetic test passed; and font metrics lie about letter-spacing, so a bake must scan its own ink. Synthetic tests share the author's assumptions — one real wire capture beats a hundred self-tests." "learning": "Tidal 1.9 addresses superdirtShape packets /dirt/play, not /play \u2014 captured off the wire, the documented address silently dropped every real packet while every synthetic test passed; and font metrics lie about letter-spacing, so a bake must scan its own ink. Synthetic tests share the author's assumptions \u2014 one real wire capture beats a hundred self-tests."
},
{
"task": "midiviz extracted to standalone opensource repo",
"date": "2026-09-25",
"where": "~/Work/Sound/midiviz (github.com/PLNech/midiviz pushed; git.nech.pl/pln/midiviz pending repo creation)",
"learning": "A branding override is a fuzzing harness in disguise: exposing the wordmark to arbitrary strings immediately found an UnboundLocalError in _word_pixmap's fit branch (pad used before assignment) that PARVAGUES could never reach \u2014 the default input only exercises the author's assumptions."
},
{
"date": "2026-09-26",
"task": "Export + master Take103 (AI ENGINEER set, partial: rec joins 3 min in, d8 never armed) and Take104 (Rose Rouge club mix) from Ardour interchange mono pairs; 4 masters (-14/-9) + 13-track split in ~/Work/Sound/Prod/AIEngineer2026_master; segments authored from gig-log track switches; fixed tidal-ears split --segments slug crash (3bafd03)",
"learning": "The Ardour interchange capture IS the export: mono %L/%R pairs + gig-log track timeline replace the DAW export pass and silence-based boundary detection entirely."
} }
] ]
\ No newline at end of file
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