The folk()/carol() helper loops one fixed melody per verse, which breaks
for songs whose chorus/refrain is musically distinct from the verse —
the helper just repeated the verse tune where the chorus should be,
silently dropping the actual chorus content from both the audio and the
highway. Rewrote 8 pieces as explicit note-by-note builders (matching the
existing Drunken Sailor/Jingle Bells pattern) with real verse+chorus
structure:
- Oh! Susanna, Camptown Races: added the missing chorus melody
- Turkey in the Straw: added the missing second fiddle strain (AABB reel)
- We Three Kings, Angels We Have Heard on High, Hark the Herald Angels
Sing, O Come All Ye Faithful: added the missing refrain
- 12 Days of Christmas: rebuilt as a genuinely cumulative structure
(day N sings N gift lines counting down to "a partridge in a pear
tree"), which a single fixed-length loop could never represent
- buildClassicalNotes() had an unreachable return after the note-building
chain, so simplifyNotes() (the Full/Simple note-density toggle) was never
applied to any isClassical piece — fixed by assigning to a variable first.
- Jingle Bells' note durations used an eighth-note-heavy pattern that
compressed the tune to roughly half its correct length instead of the
familiar quarter/half-note "Jingle bells, jingle bells" cadence — replaced
with a standard, measure-verified rhythm.
- Drunken Sailor inserted a stray extra beat between each of its 3 passes
(t+=q, one full quarter note tied to the beat grid) which broke the 4/4
pulse; changed to an off-grid pause. Also extended its chord backing to
cover the chorus (mm9-16), which previously had none on repeat passes.
- Removed O Fortuna (Orff, 1936) and Sabre Dance (Khachaturian, 1942) from
Classical, and Rudolph the Red-Nosed Reindeer (1949), Frosty the Snowman
(1950), and Winter Wonderland (1934) from Christmas — none of these are
actually public domain (all still under active copyright), despite being
filed under a "public domain compositions" list.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PbwKCCj1vwAoqgRYDoqgeL
- Linux gamepad: add axis-as-button support for Wii drums that report
hits as axis changes instead of button presses on Linux
- Linux gamepad: initialize prevBtns from actual button state on first
detection to prevent spurious triggers when controller connects
- Linux gamepad: add btn.value>0.5 check for analog button thresholding
- Linux gamepad: add gamepadconnected event listener (catches late-
connecting controllers that polling alone misses on Linux)
- Remap: add 5-second per-step countdown timeout for both gamepad and
keyboard remap; auto-skips unmapped pads (e.g. kits with fewer pads)
- Audio: add DynamicsCompressor master bus per AudioContext to prevent
clipping when multiple drums hit simultaneously
- Audio: normalize playDrumAt volumes from raw 0-8 range to 0-1 before
gain nodes; compressor handles peak limiting cleanly
- Audio: route playSynth (classical orchestral) through master bus too
https://claude.ai/code/session_01GJY5fktsdBkSUFLmePfZpv
The import panel now has 4 tabs:
- JSON: existing JSON import (unchanged)
- Text/Shorthand: type notes like "C4 quarter, D4 eighth, E4 half"
or "C4 q D4 e E4 h" — supports all duration names, rests, auto
lane assignment by pitch range
- MusicXML: import .xml/.musicxml files from MuseScore, Finale,
Sibelius, flat.io etc. Parses pitch, duration, tempo, chords,
rests, and mid-stream tempo changes
- MIDI: import .mid files with a minimal parser that handles format
0/1, tempo events, note on/off pairing, and tick-to-second conversion
All import modes support an "Append" checkbox to add to existing notes.
Lanes are auto-assigned by pitch range (high=Red, low=Kick).
https://claude.ai/code/session_01TLvDyKzUQekd9hzFuEJ5YX
Previously clicking the header set the marker but you couldn't drag it.
Now click-and-drag in the header moves the marker freely in both
directions. Auto-scrolls when dragging near canvas edges so you can
drag the marker past the visible area back toward the beginning.
https://claude.ai/code/session_01TLvDyKzUQekd9hzFuEJ5YX
After auto-scroll during preview, users couldn't easily navigate back
to the beginning to reposition the play-from marker. Added:
- "⏮ Start" button that resets scroll and play-from marker to beginning
- Home key shortcut to do the same
- End key shortcut to jump to end of piece
https://claude.ai/code/session_01TLvDyKzUQekd9hzFuEJ5YX
edUpdateNotePanel() resets pitchInput.value on every call, but it runs
on every edDraw() — including from requestAnimationFrame during preview,
mouse events, and a 30ms setTimeout(edResize) loop. This caused any
typed characters to be immediately overwritten.
Now skip overwriting INPUT/SELECT values when that element has focus,
so the user can freely type a new pitch like "A4" without it snapping
back to the old value.
https://claude.ai/code/session_01TLvDyKzUQekd9hzFuEJ5YX
Two additional window-level keydown handlers were also capturing keys when
the pitch input (or any input/select/textarea) was focused:
1. The key remap handler (capture phase) was eating all keydown events
2. The game lane input handler was calling preventDefault() on keys like
f, g, h, j, d, k, l, space — which are needed for typing pitch names
Both now skip when activeElement is an INPUT, TEXTAREA, or SELECT.
https://claude.ai/code/session_01TLvDyKzUQekd9hzFuEJ5YX
The edKeyDown handler was catching Backspace, Delete, arrow keys, and other
keys globally, even when the user was typing in the pitch input field. This
made it impossible to edit the pitch value (e.g. changing D4 to A4) because
Backspace would delete the selected note instead of editing the text.
Added a check to skip the handler when focus is on INPUT, TEXTAREA, or SELECT.
https://claude.ai/code/session_01TLvDyKzUQekd9hzFuEJ5YX
When a note is selected, a properties panel now appears with:
- Pitch input (type note names like C4, D#5, Bb3)
- Duration dropdown (whole, half, quarter, eighth, etc.)
- Lane selector dropdown
Code view now shows pitch names and duration names as comments
next to each note for easy reading. Export includes pitch/duration
names. Import and Apply Code accept note name strings in the f field.
https://claude.ai/code/session_018SvBLznyTuvoZAYCw9WwAA
Major interaction fix:
- Single click now SELECTS nearest note in same lane (not adds)
- Double-click on empty space adds a new note
- Hit detection has larger padding (+6px each side) for easier clicking
- Nearby-note search fallback: clicks within half-beat snap to closest note
Pitch editing:
- Shift+Up/Down = change pitch by one semitone
- Ctrl+Shift+Up/Down = change pitch by one octave
- Status bar shows current pitch (e.g. A4) and available shortcuts
Bug fixes:
- Reset now preserves frequency (f) field — pitch info no longer lost
- Code panel has max-height:45vh with overflow scroll, textarea resizable
- Canvas has min-height:200px so it never gets fully squished
- Help text updated to reflect new click=select, dbl-click=add behavior
https://claude.ai/code/session_01AqTWV8hPy2XcGP5KY2Q8zv
- Restored original pitches (D4, F4, A4) for Drunken Sailor M1-2 and
(C4, E4, G4) for M3-4 while keeping corrected q-ee-q-ee rhythm
- New "Pitch" toggle button shows note names (A4, C#5, etc.) below
each note on the editor canvas using frequency-to-note-name lookup
- Code labels now also show pitch name when available
- Play-from-position redesigned: single click in header sets a yellow
marker, double-click starts playback from that position. Preview
button also starts from marker. Esc clears marker.
- Header area enlarged to 32px for easier clicking
- Code panel textarea now resizable (drag to expand/shrink), removed
fixed max-height, canvas auto-resizes via ResizeObserver
- Status bar shows note value name (quarter, eighth, etc.) for selection
https://claude.ai/code/session_01AqTWV8hPy2XcGP5KY2Q8zv
Editor improvements:
- Musical notation symbols (♩♪𝅗𝅥𝅝) displayed on notes with duration
- Number keys 1-5 set note values (whole/half/quarter/eighth/sixteenth), 6-8 for dotted
- Time signature selector (4/4, 3/4, 6/8, 9/8, etc.) with measure-aware grid lines
- Double-click header to start playback from any position
- Singalong/non-Classical pieces no longer play background orchestra in editor preview
(only Classical genre gets conductor mode with bg track)
- Status bar shows note value name when selected
Drunken Sailor fix:
- Corrected rhythm to quarter-eighth-eighth pattern per sheet music
- Melody notes now store duration and frequency for proper editor display
Singalong pieces now tagged with isSingalong flag and store duration on melody notes.
https://claude.ai/code/session_01AqTWV8hPy2XcGP5KY2Q8zv
Replace the incorrect Drunken Sailor melody with an accurate
transcription from the traditional sheet music:
- Verse: repeating A4 eighth notes descending to D-F-A, then G4
pattern with C-E-G, building to B-C-D
- Chorus: "Way hey and up she rises" with dotted rhythms
- 3 passes with building instrumentation (woodwind → strings → brass)
- Proper Am/G chord backing from pass 2 onward
- Correct rhythmic values (eighths, quarters, dotted quarters, halves)
https://claude.ai/code/session_015qMeX3wFA1dcCaFp9p4vai
- Clicking Code button now toggles on-canvas labels above each note
showing {t, l, d} values so you can see the code right at the note
- Labels appear for ALL notes when Code mode is active (button turns blue)
- Selected note always shows its label regardless of Code mode
- Code panel still opens/closes alongside the labels for bulk editing
- Labels positioned above notes, flipping below if near lane top
https://claude.ai/code/session_015qMeX3wFA1dcCaFp9p4vai
- Playhead: yellow vertical line tracks current position during preview
with auto-scroll to keep it visible
- Note highlight: notes flash white with colored glow when the playhead
passes over them, so you can see which note is playing
- Fix editor layout: canvas was squished because ED_LANE_H calculation
didn't account for ED_HEAD header height, and screen overflow
prevented flex stretching
- Pattern mode playhead cycles through 0-4 beat range correctly
https://claude.ai/code/session_015qMeX3wFA1dcCaFp9p4vai
- START marker: green dashed vertical line at t=0 matching the END marker style
- Measure numbers: numbered (M1, M2, ...) in a header row at top of editor
- Note duration: notes support a `d` (duration) property, rendered as variable-width bars
with a draggable right edge to resize; D key to add/increase, Shift+D to remove
- Range select: Shift+drag on timeline to select a region (purple highlight)
- Copy/paste: Ctrl+C copies notes in selection (or single selected note),
Ctrl+V pastes at end of piece or at selection boundary
- Ctrl+A selects all notes, Escape clears selection, Delete removes range
- All save/load/export/import/code-view paths preserve the duration property
- Updated help text and status bar to document new controls
https://claude.ai/code/session_015qMeX3wFA1dcCaFp9p4vai
- Fix edPxPerSec() → edPxPerUnit() crash in edDraw() that prevented
canvas notes/lanes from rendering (only toolbar was visible)
- Add math gate prompt (simple addition) to openEditor(), hideSong(),
and hideGenre() for parental control consistency
- Refactor confirmReset() to use shared mathGate() function
https://claude.ai/code/session_01GSG2ymeVdsTegpaKVhQVFF
- Canvas uses flex:1 and align-self:stretch to fill remaining space
- edResize uses getBoundingClientRect for reliable width measurement
- Use double requestAnimationFrame instead of setTimeout for layout settling
- Minimum canvas height of 200px as fallback
https://claude.ai/code/session_01TFVkxq4PYhkSFGYHEi4uqY
Three ways to move edits between machines:
- "Bake into HTML" downloads index.html with edits embedded in the file
- "Edits File" downloads all edits as a JSON file
- "Load Edits" imports edits from a JSON file into localStorage
Baked edits act as fallback — localStorage overrides them on the new machine.
https://claude.ai/code/session_01TFVkxq4PYhkSFGYHEi4uqY
- Editor now works for regular rhythm patterns (rock, jazz, etc.) not just classical
- Added code view toggle showing JS array notation for notes/patterns
- Added import panel for pasting JSON note data or loading .json files
- Preview mode handles both classical (synth orchestra) and regular (drum sounds)
- buildNotes() now checks localStorage for user-saved pattern edits
- Fixed edPreview() to play drum patterns with proper bar looping
https://claude.ai/code/session_01TFVkxq4PYhkSFGYHEi4uqY
New editor screen lets users fix incorrect melodies without editing code:
- Canvas-based timeline with 5 lane rows (Red/Yellow/Blue/Green/Kick)
- Click to add notes, click existing notes to select, drag to move
- Delete/Backspace to remove selected note
- Arrow keys to nudge timing and lane
- Beat grid snapping (1/4 beat resolution)
- BPM adjustment
- Zoom slider for timeline scale
- Preview with orchestral background + melody clicks
- Save to localStorage (auto-loaded when playing the piece)
- Copy JSON to clipboard for sharing corrections
- Reset button to restore original melody
- Edit button appears in menu only for classical pieces
Edits are loaded in buildClassicalNotes() so saved corrections
are used during gameplay automatically.
https://claude.ai/code/session_01TFVkxq4PYhkSFGYHEi4uqY
Replaced 5-line tp() call with full conductor-style arrangement:
- chromRun() helper plays fast chromatic scales in background,
only every 4th note is hittable (conducting the accent peaks)
- 7 sections: intro → first chromatic runs → development →
E minor modulation → fff recapitulation → climax → coda
- Three speed tiers (0.09s, 0.065s, 0.055s per note) for
increasing intensity across sections
- Continuous Am harmonic bed with strings/bass
- Duration expanded from ~35s to ~88s
https://claude.ai/code/session_01TFVkxq4PYhkSFGYHEi4uqY