From ca525d68822172cf9c1f7869d4254221891149c8 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Tue, 18 Aug 2026 14:05:20 -0400 Subject: [PATCH] =?UTF-8?q?loner:=20syllable=20cuts=20are=20measurements?= =?UTF-8?q?=20too=20=E2=80=94=20the=20snapper=20was=20undoing=20them?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The my/self split was set to 4.50, where her /s/ begins, and came back out of the build at 4.715 — back inside the fricative, the exact place it was moved away from. Cause: only `times` pins were exempt from the boundary snapper. A syllable cut is just as measured, and the snapper was free to drag it up to 250 ms. Both kinds of measured boundary are now authoritative. Verified: my 3.890–4.500, self 4.500–5.235, against a fricative that starts at 4.50. This is the third time today a correction has been silently undone downstream of itself — first the notes that kept an aligner's stale pitch after being repinned, then the pins the snapper dragged, now the splits. Worth remembering the shape of it: a fix that lands upstream of an automatic correction has to be marked as intentional, or the automation treats it as noise. --- pop/loner/bin/halo3.py | 8 +++++++- pop/loner/vox4/.chart.json | 14 +++++++------- pop/loner/vox4/.manifest.json | 27 +++++++++++---------------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/pop/loner/bin/halo3.py b/pop/loner/bin/halo3.py index 6c7bdb09d..b08662f75 100644 --- a/pop/loner/bin/halo3.py +++ b/pop/loner/bin/halo3.py @@ -882,6 +882,7 @@ for name, ch in CHART.items(): # single unit made the pluck play one note against three, and left # the word as a lump the bar map could not place. Cutting it into # real syllables gives each its own note, slot and beat. + syll_pins = set() for wi in sorted((ch.get("sylls") or {}), reverse=True): base = words[wi] cuts = ch["sylls"][wi] @@ -891,11 +892,16 @@ for name, ch in CHART.items(): labels = [head] + [c[1] for c in cuts] words[wi:wi + 1] = [dict(base, start=edges[k], end=edges[k + 1], t=labels[k]) for k in range(len(labels))] + syll_pins.update(labels[1:]) # a measured cut is a measurement too # words pinned by `times` were measured off her own onsets; the # snapper must not then drag them somewhere else. Indices shift # by the syllable splits inserted before them. - pinned = set() + # Boundaries we MEASURED — `times` pins and syllable cuts alike — must + # survive the snapper. It moved the my/self cut from the 4.50 s start + # of her /s/ to 4.715, back inside the fricative, which is the bug it + # was supposed to fix. + pinned = {i for i, w in enumerate(words) if w["t"] in syll_pins} for wi in (ch.get("times") or {}): extra = sum(len([c for c in cs if c[0] is not None]) for si, cs in (ch.get("sylls") or {}).items() if si < wi) diff --git a/pop/loner/vox4/.chart.json b/pop/loner/vox4/.chart.json index 73b5867a0..93c485d9e 100644 --- a/pop/loner/vox4/.chart.json +++ b/pop/loner/vox4/.chart.json @@ -5,10 +5,10 @@ "voiced": [ [ -0.0407, - 12.4542 + 13.0337 ], [ - 12.4948, + 13.054, 18.3203 ], [ @@ -21,11 +21,11 @@ ], [ 32.4622, - 42.3035 + 42.3645 ], [ - 42.4052, - 47.4478 + 42.4357, + 47.4377 ], [ 47.4783, @@ -88,7 +88,7 @@ "dur": 2.0, "st": 2, "t": "self", - "lead": 0.0203 + "lead": 0.0 }, { "beat": 14.5, @@ -172,7 +172,7 @@ "dur": 2.5, "st": 5, "t": "tient", - "lead": 0.183 + "lead": 0.122 }, { "beat": 45.0, diff --git a/pop/loner/vox4/.manifest.json b/pop/loner/vox4/.manifest.json index 638a07aef..2b96cf6db 100644 --- a/pop/loner/vox4/.manifest.json +++ b/pop/loner/vox4/.manifest.json @@ -31,11 +31,11 @@ [ "my", 3.89, - 4.715 + 4.5 ], [ "self", - 4.715, + 4.5, 5.235 ], [ @@ -71,36 +71,36 @@ [ "wait", 12.67, - 13.68 + 13.7 ], [ "ing", - 13.68, + 13.7, 14.4 ], [ "ve", 14.4, - 15.21 + 15.05 ], [ "ry", - 15.21, + 15.05, 15.52 ], [ "pa", 16.04, - 16.785 + 16.8 ], [ "tient", - 16.785, + 16.8, 17.215 ], [ "ly", - 17.695, + 17.7, 18.54 ], [ @@ -132,17 +132,12 @@ "curled +65ms", "in +80ms", "my -50ms", - "self +215ms", "i +180ms", "think -45ms", "a -40ms", "stone -45ms", "just +80ms", - "ing -20ms", - "ry +160ms", - "pa +80ms", - "tient -15ms", - "ly -5ms" + "pa +80ms" ], "trims": [ "up \u2212420ms", @@ -151,7 +146,7 @@ "stone \u2212675ms", "just \u2212295ms", "ry \u2212520ms", - "tient \u2212480ms", + "tient \u2212485ms", "time \u2212795ms" ], "words": "the whole lyric, one take" -- 2.51.2