feat(boot): kill the global gain that lived on a fader — and free fader 1 for d1
PLN, 2026-07-29: "midiGlobal can be killed imo. so yea please do the refactor of
boottidal so we can free gain track1".
`midiGGlobal = orDef 0.769 "^77" * 1.3` read the LIVE fader, and that was wrong twice
over. First as SAFETY: it put a global gain on ONE physical fader, so brushing past
fader 1 in the dark attenuated every midiG-using stream at once — the whole set, quietly,
with nothing on screen to explain it. A control that can silence everything should not be
reachable by accident. Second as ERGONOMICS: CC77 being read by Tidal is what kept the
surface one lane off. Ardour has learned CC 78-84, CC77 is free, and with Tidal no longer
reading it the eight faders can finally line up fader N -> dN instead of fader N -> d(N-1)
(#46). Any track that reached for a fader was reaching one to the right of the orbit it
was thinking about.
Now a fixed pre-set: `midiGGlobal = 1.0`. Deliberately inaudible — the old untouched
default evaluated to 0.769 * 1.3 = 0.9997, so every existing track moves by 0.003 dB.
Global headroom is still adjustable, but it is one number in one place rather than
something a hip can knock.
NOT retired: the midiG family itself. PLN thought he no longer used it ("i dont use
midiGs anymore iirc since ardour faders"), and behaviourally he is right -- with the
global term gone, `midiG' ch l h` reduces to plain `gain (range l h ch)`. But the NAME is
called in 167 files (`midiG'`) plus 12 (`midiG`), and deleting a definition the corpus
references is a Haskell compile error, which takes the whole `let` block down and
silences the entire track. That is the exact failure mode of the last two debugging
evenings, and five days from OPAL is not when to re-open it. Retiring the usage is a
post-gig corpus migration, sibling to #64.
Verified with tools/check-boot.sh: the helper block typechecks against tidal-1.9.5 under
`ghc -fno-code`, the #55 seed block typechecks, and all 13 g* helpers (including
midiGdef, which is the one this edit could plausibly have broken) still yield events with
an UNTOUCHED controller. Not "no error appeared" -- the helpers were run against an empty
control map and their event counts checked.
Also lands tools/at/lens.py: infers WHICH MEASUREMENT can see a given control from the
track's own source, so a per-track acceptance test can assert "this knob measurably moves
the orbit it is wired to" without using a lens that is blind to the effect. rms cannot see
a filter or a bitcrusher -- they rearrange the spectrum and leave the level alone -- so an
rms-based "did anything change?" reports a confident NO on an effect that works perfectly.
Classifies 96.7% of the corpus's 5046 control bindings (33% unknown -> 3.3% once the
scanner looked at a 3-line window instead of one line, because Tidal expressions wrap and
an unclassified control is one the suite silently SKIPS -- precisely the controls most
likely to be broken). 41 unit tests, every positive case a real corpus line, with a
coverage guard so a future edit cannot quietly regress the scan.
Showing
tools/at/lens.py
0 → 100644
This diff is collapsed.
Click to expand it.
tools/at/tests/test_lens.py
0 → 100644
Please
register
or
sign in
to comment