Skip to content

fix(editor): flatten a variable tempo map to a constant BPM - #140

Merged
byrongamatos merged 1 commit into
mainfrom
fix/editor-tempo-flatten
Jul 9, 2026
Merged

fix(editor): flatten a variable tempo map to a constant BPM#140
byrongamatos merged 1 commit into
mainfrom
fix/editor-tempo-flatten

Conversation

@ChrisBeWithYou

@ChrisBeWithYou ChrisBeWithYou commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

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 as
    a uniform 60/bpm grid — each beat re-timed to t0 + i·(60/bpm), keeping
    every 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). Spacing is exact
    (unrounded)
    on purpose — _r3's ±0.5 ms would drift the 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 a variable map,
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 (72/72).

Summary by CodeRabbit

  • New Features

    • When entering a BPM for songs with variable tempo maps, the editor now prompts to flatten the entire tempo map to a single constant BPM.
    • Flattening rebuilds the beat grid using uniform BPM spacing while preserving measure/time-signature info and the original start offset, keeping alignment with audio.
  • Bug Fixes

    • Fixes an issue where BPM sync points couldn’t all be removed without deleting measures.
    • The flattening change is now captured as a single undoable action and reports completion after success.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: eeb58574-56bb-49f2-9a71-7952a8dbe088

📥 Commits

Reviewing files that changed from the base of the PR and between be13f61 and c15e967.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • screen.js
  • tests/tempo_flatten.test.js

📝 Walkthrough

Walkthrough

Adds BPM-driven flattening for variable tempo maps, using a new pure helper, an undoable TempoGridCmd flow, validation tests, and a changelog update.

Changes

Tempo Map Flattening

Layer / File(s) Summary
Flatten confirmation flow and undo integration
screen.js
BPM entry on variable-tempo songs now prompts to flatten the map to a constant BPM, applies the change through TempoGridCmd, updates the BPM display, redraws, or exits early on rejection or failure.
Pure flatten-to-BPM computation
screen.js
Adds _tempoFlattenToBpmPure, which validates beats and BPM inputs, computes uniform spacing from 60/bpm, and returns a cloned beats array with retimed entries or null on invalid input.
Test harness and flatten validation tests
tests/tempo_flatten.test.js
Adds a Node test runner that extracts the pure tempo helpers from screen.js, builds a variable-tempo fixture, and verifies flattening behavior, metadata preservation, origin anchoring, and invalid-input handling.
Changelog entry
CHANGELOG.md
Adds a changelog entry describing the tempo flattening behavior and the referenced test file.

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
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: flattening variable tempo maps to a constant BPM in the editor.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/editor-tempo-flatten

Comment @coderabbitai help to get the list of available commands.

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
byrongamatos force-pushed the fix/editor-tempo-flatten branch from be13f61 to c15e967 Compare July 9, 2026 07:51
@byrongamatos
byrongamatos merged commit 4e1eacd into main Jul 9, 2026
2 of 3 checks passed
@byrongamatos
byrongamatos deleted the fix/editor-tempo-flatten branch July 9, 2026 07:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants