Commit 57745a7c by PLN (Algolia)

fix(joins): the close clip was labelled "dry" while shipping a reverb tail

build_release_joins hardcoded its first closing clip as CLOSE · DRY, "what ships
today". That was true exactly once — before any reverb was chosen. The clip is
cut from the RENDERED last track, so the moment PLN picked a preset the file he
auditioned had the echo baked in and the label said it did not.

An audition UI that misdescribes what ships is the one bug this tool cannot
have: its entire job is to let the ear check the actual artefact, and a wrong
label turns a passed listen into a false clearance. Same family as the earlier
allow-list that silently dropped reverb_preset — the output looked clean and was
clean, of the wrong thing.

Now the first entry is CLOSE · SHIPPED and reads the preset out of the release
segments, so it renders as "SHIPPED · MORE tail baked in". Names the artefact
from the data that produced it rather than from an assumption frozen at the time
the code was written. Wrapped in try/except: a missing segments file drops the
suffix rather than blocking the audition.

The A/B variants are unchanged and still opt-in behind --close-ab.
parent 271e07c0
...@@ -176,7 +176,20 @@ def main() -> int: ...@@ -176,7 +176,20 @@ def main() -> int:
# --- closing: does the record END, or merely stop # --- closing: does the record END, or merely stop
tail_len = min(a.tail + 10, durs[-1]) tail_len = min(a.tail + 10, durs[-1])
ss = max(0.0, durs[-1] - tail_len) ss = max(0.0, durs[-1] - tail_len)
variants = [("dry", None)] + ([(k, CLOSE_AB[k]) for k in CLOSE_AB] if a.close_ab else []) # The FIRST entry is never "dry" — it is the last track exactly as rendered,
# which by now has the ear-chosen reverb baked in. Labelling it "dry" told
# PLN the record ended without an echo while the file he was auditioning had
# one, i.e. the audition UI lying about what ships, which is the single
# failure this whole tool exists to prevent. So name it from the segments.
shipped = ""
try:
rel = json.loads(Path(spec["segmentsRelease"]).read_text())
last = (rel["segments"] if isinstance(rel, dict) else rel)[-1]
if last.get("reverb_preset"):
shipped = f" · {last['reverb_preset'].upper()} tail baked in"
except Exception:
pass # a missing segments file must not block audition
variants = [("shipped", None)] + ([(k, CLOSE_AB[k]) for k in CLOSE_AB] if a.close_ab else [])
for i, (name, echo) in enumerate(variants): for i, (name, echo) in enumerate(variants):
cl = joins_dir / f"99{i}-close-{name}.flac" cl = joins_dir / f"99{i}-close-{name}.flac"
if not close_variant(files[-1], cl, ss, tail_len, a.wet, echo): if not close_variant(files[-1], cl, ss, tail_len, a.wet, echo):
...@@ -184,14 +197,14 @@ def main() -> int: ...@@ -184,14 +197,14 @@ def main() -> int:
rows.append({ rows.append({
"track": 99 + i, "track": 99 + i,
"title": f"CLOSE · {name.upper()}" + (f" · {a.wet:.0f}s reverb tail" "title": f"CLOSE · {name.upper()}" + (f" · {a.wet:.0f}s reverb tail"
if echo else " (as rendered)"), if echo else shipped),
"fromTitle": title_of(files[-1]), "nominal": tail_len, "fromTitle": title_of(files[-1]), "nominal": tail_len,
"clipStart": 0.0, "clipEnd": ffprobe_dur(cl), "clipStart": 0.0, "clipEnd": ffprobe_dur(cl),
"url": f"/audio/joins/{cl.name}", "url": f"/audio/joins/{cl.name}",
"peaks": [round(x, 4) for x in peaks(cl, PEAKS_N)], "peaks": [round(x, 4) for x in peaks(cl, PEAKS_N)],
"marks": [{"key": "join", "label": "record ends", "t": tail_len}], "marks": [{"key": "join", "label": "record ends", "t": tail_len}],
"settled": False, "noCandidate": False, "settled": False, "noCandidate": False,
"note": ("Last sound of the album, dry — what ships today." "note": (f"Last sound of the album, exactly as rendered{shipped}."
if echo is None else if echo is None else
f"A/B option '{name}': the last {a.wet:.0f}s get an echo that " f"A/B option '{name}': the last {a.wet:.0f}s get an echo that "
f"rings past the final sample. Everything before the tail is " f"rings past the final sample. Everything before the tail is "
......
...@@ -12914,12 +12914,12 @@ ...@@ -12914,12 +12914,12 @@
}, },
{ {
"track": 99, "track": 99,
"title": "CLOSE \u00b7 DRY (as rendered)", "title": "CLOSE \u00b7 SHIPPED \u00b7 MORE tail baked in",
"fromTitle": "REVOLUTION", "fromTitle": "REVOLUTION",
"nominal": 30.0, "nominal": 30.0,
"clipStart": 0.0, "clipStart": 0.0,
"clipEnd": 30.0, "clipEnd": 30.0,
"url": "/audio/joins/990-close-dry.flac", "url": "/audio/joins/990-close-shipped.flac",
"peaks": [ "peaks": [
0.5388, 0.5388,
0.213, 0.213,
...@@ -13831,7 +13831,7 @@ ...@@ -13831,7 +13831,7 @@
], ],
"settled": false, "settled": false,
"noCandidate": false, "noCandidate": false,
"note": "Last sound of the album, dry \u2014 what ships today." "note": "Last sound of the album, exactly as rendered \u00b7 MORE tail baked in."
} }
] ]
} }
\ 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