feat(editor): enharmonic flat-key note spelling (4.16a follow-up) - #207
Conversation
Roll note labels, the add-note pitch readout, roll placement messages, and the Detect announcement spell flats in flat keys (Bb4, never A#4), via a pure relative-major preference table in theory.js. midiToNote gains an optional names argument, defaulting to the historical sharp table; the key picker stays sharp-named and F#/Gb spells sharp to match it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EBQCHCNA81E9tHmSDHSe2Q
|
Warning Review limit reached
Next review available in: 15 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughAdds key-aware enharmonic note spelling, selecting flat or sharp names from the editor key and applying them to piano-roll labels, dialogs, chord and fretboard readouts, position confirmation, and detected-key output. Tests cover key preferences, fallbacks, MIDI conversion, and editor state changes. ChangesEnharmonic note spelling
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Editor as Editor UI
participant State as S.editorKey
participant Names as editorKeyNoteNames
participant MIDI as midiToNote
Editor->>State: read active editor key
State-->>Names: provide key
Names->>MIDI: provide flat or sharp table
MIDI-->>Editor: return key-spelled note label
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Two note-name surfaces still hard-coded the sharp table after 4.16a: the fretboard strip's open-string labels (fretboard-strip.js) and the chord-identification root name (main.js _identifyChordPure call). In a flat key with accidental open strings (Eb tuning / capo) or a chord whose root is a black key, they read A#/D#/C#m while the roll read Bb/Eb/Dbm. Both now index the same key-aware table the roll uses (_noteNamesForKeyPure(S.editorKey) / editorKeyNoteNames()), so spelling is consistent everywhere. Chord readout is only root+suffix, so respelling the root letter is the whole visible fix; full functional chord spelling (accidentals on non-root tones) stays out of scope. Pure display only — no pitch/chart mutation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…labels # Conflicts: # CHANGELOG.md
What
Note names follow the song key's spelling convention (the 4.16a follow-up queued behind #200, which shared the draw.js region): with a flat key set, the editor writes Bb4, never A#4 —
Sharp keys and no-key-set keep today's sharp names exactly. The C-octave row labels on the keyboard gutter are untouched (C is never enharmonic).
The convention
A key signature spells its accidentals one way, decided by the relative major's side of the circle of fifths — so every mode borrows its signature's spelling (D dorian → C major → sharps; G dorian → F major → flats; C minor → Eb major → flats). Flat majors: Db, Eb, F, Ab, Bb. F#/Gb stays sharp because the key picker's tonic list is sharp-named — the label must match the choice; the picker itself keeps sharp-named ids (stable localStorage values).
chromaticand unknown scales default to sharps.How
theory.js(pure):PIANO_NOTE_NAMES_FLAT,_keyPrefersFlatsPure(tonic, scale)(relative-major offset table, wrap-safe on out-of-range tonics),_noteNamesForKeyPure(key)(null/malformed → the sharp table, same ref).keys.js:midiToNote(midi, names?)— optional table, defaulting to the historical sharp spelling so every existing call site is behavior-identical;editorKeyNoteNames()resolves the activeS.editorKey's table for display call sites.draw.js,add-note.js,main.js(_rollConfirmPosition),key-view.js(Detect status) pass the key-aware table. No wire/pack change anywhere — spelling is a view concern.Tests
tests/flat_key_labels.test.mjs(9, real-import ESM; fails on main — the spelling exports don't exist there): flat-table shape, the full flat/sharp major split, minors + harmonic/melodic borrowing the relative signature, all seven modes + pentatonics/blues, chromatic/garbage/wrapping tonics,_noteNamesForKeyPureref semantics,midiToNotedefault-unchanged + flat respelling, andeditorKeyNoteNamesfollowingS.editorKey.Full suite 102/102; ESLint clean.
🤖 Generated with Claude Code
https://claude.ai/code/session_01EBQCHCNA81E9tHmSDHSe2Q
Summary by CodeRabbit
New Features
Tests