You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Per-section sync 3/5: per-section alignment engine (chroma + DTW per section, with confidence) #24
Part of #8. Can start in parallel with the design decision; it only produces numbers, it does not change timestamps.
Reuse the chroma + DTW alignment from the current uniform sync redesign, but run it per section instead of once for the whole song.
Scope
Use the arrangement's existing sections[] markers (Intro / Verse / Chorus / Solo / ...) as region boundaries.
For each section, anchor on its opening notes against the audio for that region and produce a per-section (factor, offset) or a set of anchor correspondences.
Produce a per-section confidence so a bad match on one section can be reported and skipped without affecting the others.
Pure analysis: return results, do not modify note timestamps (baking is sub-issue 4).
Acceptance criteria
On a synthetic or fixture song whose tempo changes at a section boundary, the per-section factors differ and each is closer to the truth than a single global factor (state the metric).
A deliberately mismatched section gets a low confidence and does not change the others' results.
Single-section songs reduce to the uniform model's result.
Out of scope
Applying the warp, the data model (sub-issue 2), and any UI (sub-issue 5).
Per-section alignment engine (#24) is complete, tested, and open as PR #69 (vs main, not merged).
Fix of the merge-blocking P1: the chain place is computed at the section's FIRST NOTE (sourceTimes[0]), not at the boundary, so a section whose notes start inside/past its marker keeps the marker's place.
Root-cause fix for the isolation guarantee: with on-the-beat clicks, every period-shifted window fits a straight line, so min-MAD could never pin the intercept — absolute place comes from the chain (audioStart snapped to a real onset). The tight window is [audioStart, audioStart + slope·span + tailPad]; the lower edge is the snapped onset itself (previous-section content never enters), and the snap prefers the onset at-or-after the chained place (a stray prior-section click that edges a few tens of ms closer no longer hijacks the boundary).
Suite now proves the hard case: on a song whose audio kinks 132→108 BPM at a boundary, a deliberately mismatched middle section reads low-confidence while the sections before and after it stay byte-for-byte identical — and a separate regression pins the marker-place rule.
No new work needed — this issue is already implemented and merged.
PR #69 is merged into main; HEAD (4e1acb9, feat(sync): per-section alignment engine (#24)) contains src/section-sync.js and tests/section_sync.test.mjs.
Verified against the current tree: node tests/section_sync.test.mjs = 14/14 and npm test = 401 pass / 0 fail. All three acceptance criteria (per-section factors beat the best single global fit; a mismatched section reads low confidence and leaves its neighbours byte-for-byte identical; a single section reduces to the uniform factor) are covered.
The implementation is pure analysis (no timestamp mutation, no UI), matching the issue scope.
Closing the issue as completed, since the tracked work is on main.
Activity
pullfrog commentedon Oct 2, 2026
test: point the pinned uniform-sync baseline at the issue that retire…
test: pin the uniform sync's do-no-harm guarantee on a meter change (#22
pullfrog commentedon Oct 11, 2026
Per-section alignment engine (#24) is complete, tested, and open as PR #69 (vs
main, not merged).sourceTimes[0]), not at the boundary, so a section whose notes start inside/past its marker keeps the marker's place.audioStartsnapped to a real onset). The tight window is[audioStart, audioStart + slope·span + tailPad]; the lower edge is the snapped onset itself (previous-section content never enters), and the snap prefers the onset at-or-after the chained place (a stray prior-section click that edges a few tens of ms closer no longer hijacks the boundary).low-confidencewhile the sections before and after it stay byte-for-byte identical — and a separate regression pins the marker-place rule.Tests:
node tests/section_sync.test.mjs= 14/14;npm test= 401 pass / 0 fail;npm run lint= 0 errors (3 pre-existing warnings).Task list (2/6 completed)
big-pickle(free) | 𝕏feat(sync): per-section alignment engine (#24)
pullfrog commentedon Oct 12, 2026
No new work needed — this issue is already implemented and merged.
main; HEAD (4e1acb9,feat(sync): per-section alignment engine (#24)) containssrc/section-sync.jsandtests/section_sync.test.mjs.node tests/section_sync.test.mjs= 14/14 andnpm test= 401 pass / 0 fail. All three acceptance criteria (per-section factors beat the best single global fit; a mismatched section reads low confidence and leaves its neighbours byte-for-byte identical; a single section reduces to the uniform factor) are covered.Closing the issue as completed, since the tracked work is on
main.big-pickle(free) | 𝕏feat(sync): per-section sync results UI (#26) (#71)