fix(editor): flatten a variable tempo map to a constant BPM - #140
Merged
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds BPM-driven flattening for variable tempo maps, using a new pure helper, an undoable ChangesTempo Map Flattening
Estimated code review effort: 2 (Simple) | ~15 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant screenjs as screen.js
participant tempoFlatten as _tempoFlattenToBpmPure
participant tempoGridCmd as TempoGridCmd
User->>screenjs: Type BPM value
screenjs->>screenjs: Detect variable tempo map
screenjs->>User: Confirm flatten whole map
User->>screenjs: Accept
screenjs->>tempoFlatten: Flatten beats to constant BPM
tempoFlatten-->>screenjs: New beats array or null
alt flatten succeeded
screenjs->>tempoGridCmd: Record tempo map change
screenjs->>screenjs: Update BPM display and redraw
else flatten failed or declined
screenjs->>screenjs: Update BPM display and return
end
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Tester report: a GP8 import produced a variable per-measure tempo map (wrong, wobbling BPM) and there was "no way to remove all the BPM sync points without deleting measures." The per-measure BPM editor can only fix ONE measure at a time, and typing a BPM on such a song just refused with "Use Tempo Map to edit songs with multiple tempo events." That refusal now becomes an offer: typing a BPM on a variable map asks whether to FLATTEN the whole map to that one constant BPM. - @pure:tempo-map-bpm: _tempoFlattenToBpmPure rebuilds the beat grid as a uniform 60/bpm grid — every beat re-timed to t0 + i*(60/bpm), keeping each beat's measure / time-signature metadata and the first beat's start time. Spacing by 60/bpm matches how the editor already defines a measure's BPM (beatCount*60/span; see _tempoMeasureBpmsPure). Exact (unrounded) spacing on purpose - _r3's +/-0.5ms would drift per-measure BPM past the 0.01 variable-tempo detector and the grid would still read as variable. - window.editorSetBPM: on a variable map, confirm() then flatten via one undoable TempoGridCmd. Notes are NOT touched - they keep their times so they stay aligned to any audio; undo restores the original tempo map. Tests: tests/tempo_flatten.test.js (5) - the sample grid really is variable, flatten yields a uniform 60/bpm grid with metadata + origin preserved, the result round-trips to a constant BPM through the reader, a non-zero origin is kept, and the adversarial guards (too-few beats / bad bpm / null) return null without throwing. All fail on main. Full JS suite green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013JgxKh99UAeQqmhzSc73tv Signed-off-by: ChrisBeWithYou <chris@rifflarr.local>
byrongamatos
force-pushed
the
fix/editor-tempo-flatten
branch
from
July 9, 2026 07:51
be13f61 to
c15e967
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
A tester reported that a variable-tempo import (a GP8 file that came in with a
wobbling per-measure tempo map) had "no way to remove all the BPM sync points
without deleting measures." The per-measure BPM editor only fixes one measure
at a time, and typing a BPM on such a song just refused: "Use Tempo Map to edit
songs with multiple tempo events."
This turns that dead end into an escape hatch: typing a BPM on a variable
tempo map now offers to flatten the whole map to that one constant BPM.
How
_tempoFlattenToBpmPure(@pure:tempo-map-bpm) rebuilds the beat grid asa uniform
60/bpmgrid — each beat re-timed tot0 + i·(60/bpm), keepingevery beat's measure / time-signature metadata and the first beat's start
time. Spacing by
60/bpmmatches how the editor already defines a measure'sBPM (
beatCount·60/span, see_tempoMeasureBpmsPure). Spacing is exact(unrounded) on purpose —
_r3's ±0.5 ms would drift the per-measure BPMpast the
0.01variable-tempo detector and the grid would still read asvariable.
window.editorSetBPM: on a variable map,confirm()then flatten via oneundoable
TempoGridCmd. Notes are not touched — they keep their times sothey stay aligned to any audio; undo restores the original tempo map.
Tests
tests/tempo_flatten.test.js(5) — the sample grid really is a variable map,flatten yields a uniform
60/bpmgrid with metadata + origin preserved, theresult round-trips to a constant BPM through the reader, a non-zero origin is
kept, and the adversarial guards (too-few beats / bad bpm / null) return
nullwithout throwing. All fail on
main. Full JS suite green (72/72).Summary by CodeRabbit
New Features
Bug Fixes