A single-page web app that lets you click piano keys to form chords, then appends them as ABC notation to a growing text output. You know which keys you're pressing but not ABC notation — this tool bridges that gap.
Open index.html in any browser. No build step, no dependencies (abcjs is loaded from CDN).
- Click piano keys to select notes (they highlight blue and play a tone)
- Each new note replays all selected notes together so you hear the chord forming
- Press Spacebar to replay the current chord at any time
- The chord name appears live as you select notes (e.g. "Cmaj", "Abmin / G#min")
- Click Add this chord to append the selected notes as ABC notation
- Use Clear keys to deselect all keys, Undo or Clear all as needed
- Undo restores the removed chord's notes back onto the keyboard
- Click a line in the textarea to preview it — keys light up yellow and the chord plays
- While previewing, click keys to edit that chord in-place (add/remove notes)
- Use Up/Down arrow keys in the textarea to step through chords
- Click Load .abc to import an existing ABC file; Download .abc to save
- The rendered music staff on the right updates live to verify your notation
index.html— markup and structurestyle.css— all stylesapp.js— all application logic
No build step. The only external dependency is abcjs loaded from CDN for staff rendering.
- 5 octaves: C1 through B5 (60 keys total: 35 white, 25 black)
- CSS-rendered with
<div>elements; black keys absolutely positioned over white keys - Each key stores its MIDI note number as a
data-midiattribute - Black key labels use the musician-preferred spelling (Db, Eb, Ab, Bb) except F# which stays as F#
The tool makes opinionated choices about sharp vs flat spelling to match what musicians expect:
Preferred root names for black keys:
| Piano Key | Sharp | Flat | Preferred |
|---|---|---|---|
| C#/Db | C# | Db | Db |
| D#/Eb | D# | Eb | Eb |
| F#/Gb | F# | Gb | F# |
| G#/Ab | G# | Ab | Ab |
| A#/Bb | A# | Bb | Bb |
Chord tone spelling: Each note within a chord is spelled based on its interval from the root using music-theory-correct letter offsets. For example:
- Fdim (F, Ab, B) →
[F,_A,B,]— the G# is written as_A(Ab) because it's the minor 3rd of F, and the expected letter for a 3rd is A, not G - Ebmin → uses
_E(Eb) and_G(Gb) where appropriate - The tool avoids unusual enharmonics (Cb, E#, Fb, B#) — if a theoretically correct spelling lands on a white key, the natural name is used instead (e.g. B instead of Cb)
Chord name display: When the root is a black key, both enharmonic names are shown in the live display (e.g. "Abmin / G#min"). The ABC output uses the preferred spelling.
How it works internally: Each chord pattern stores letterOffsets — the expected scale-degree jumps from the root letter. When a chord is identified, each note's pitch class is compared against the expected letter to determine if it needs a sharp (^), flat (_), or natural. This is done by the noteSpelling() function.
| Octave | Style | Example |
|---|---|---|
| C1–B1 | Uppercase + ,,, |
C,,, _D,,, B,,, |
| C2–B2 | Uppercase + ,, |
C,, _D,, B,, |
| C3–B3 | Uppercase + , |
C, _A, B, |
| C4–B4 | Uppercase | C _E B |
| C5–B5 | Lowercase | c _a b |
- Single notes output bare:
C - Chords wrapped in brackets, sorted low-to-high:
[CEG] - Sharps:
^C,^F— Flats:_D,_A - Each line includes a
%comment with human-readable note names and octave numbers for easy reference:[C,EG] % C3 E4 G4
- Recognizes: maj, min, 7, maj7, min7, dim, dim7, aug, sus2, sus4, 6, min6, 9, maj9, min9
- Detection works across all inversions by trying each note as a potential root
- Identified chords are prefixed in the ABC output as chord symbols:
"Cmaj"[CEG] - Chord name shown live above the keyboard as notes are selected
- Web Audio API with Salamander Grand Piano samples (C2–C7)
- Samples are pre-fetched on page load and decoded on first user interaction
- Notes between sample points are pitch-shifted using
AudioBufferSourceNode.detune - Exponential gain decay over ~2s
- Selecting a note replays all selected notes together (volume scaled by
1/sqrt(n)to prevent clipping) - Deselecting a note is silent
- Spacebar replays the current chord on demand (disabled when textarea is focused)
- Thanks to gregjopa.com for the pointers on piano sample playback with Web Audio API
- Uses abcjs loaded from CDN to render ABC notation as SVG
- Displayed side-by-side with the textarea for live visual verification
- Styled for dark theme (light notes on dark background, yellow chord symbols)
- Updates automatically on every change
- Load .abc: Imports an ABC file, parsing header fields and body tokens; rejects invalid files
- Download .abc: Saves the current output; uses the loaded filename if available, otherwise
chords.abc - Lyrics lines (
w:) are preserved from loaded files but are non-interactive (can't be selected or edited, arrow keys skip past them)
- Read-only; all edits happen through the UI (adding chords, editing via preview, undo)
- Syntax coloring via overlay: header lines grey, chord lines cyan, lyrics lines green
- When a chord is selected for preview, non-selected lines dim to focus attention
- Hover highlights indicate clickable chord lines
- Arrow key navigation skips non-chord lines (lyrics, bar lines) and scrolls to keep trailing lyrics visible
- The ABC output is managed as a header string + array of tokens
- Undo removes the last token and restores its notes onto the keyboard
- Clear all empties the token array and resets the header
- Header is pre-populated:
X:1,T:Untitled,M:4/4,L:1/4,K:C
- Uses standard MIDI: C4 = 60, calculated as
(octave + 1) * 12 + noteIndex - Range: MIDI 24 (C1) through MIDI 83 (B5)
- No note duration control (everything defaults to
L:1/4) - No sustain/pedal simulation
- No MIDI input support
- No playback of the full ABC output