feat(editor): drum velocity authoring — Alt-drag, nudge keys, ghost pull, import velocity carry-through - #111
Conversation
|
Warning Review limit reached
Next review available in: 22 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 (4)
📝 WalkthroughWalkthroughAdds drum velocity authoring in the editor, preserves imported source velocities, updates ghost-toggle undo semantics, and adds tests plus changelog documentation. ChangesDrum velocity authoring
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant screen_js as screen.js
participant SetDrumVelocityCmd
participant EditHistory
User->>screen_js: Alt+drag on drum hit
screen_js->>screen_js: _drumEditorOnVelocityDragMove(y)
screen_js->>screen_js: preview h.v update
User->>screen_js: release drag
screen_js->>screen_js: _drumEditorOnVelocityDragEnd()
screen_js->>SetDrumVelocityCmd: commit velocity change
SetDrumVelocityCmd->>EditHistory: push undoable command
User->>screen_js: undo
EditHistory->>SetDrumVelocityCmd: rollback()
SetDrumVelocityCmd->>screen_js: restore original v or delete v
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@screen.js`:
- Around line 14847-14853: Update _drumEditorSetVelocity so that when the
selected hit velocity is raised above the ghost threshold, any existing g:true
flag is cleared as part of the same edit. This likely belongs in
SetDrumVelocityCmd (or the command path it uses) so v and g stay in sync for
selected refs, preserving the ghost/quiet invariant used by the editor and
importer.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 7a28ca24-e46d-4c59-9b18-fe028fa6f796
📒 Files selected for processing (4)
CHANGELOG.mdroutes.pyscreen.jstests/drum_velocity.test.js
…ull, import carry-through
Roadmap 4.5. Velocity always rendered and imported but authoring wrote a
hardcoded v:100 with no way to change it.
- Alt+vertical-drag on selected hits edits velocity live (up = louder,
1 step/px off each hit's ORIGINAL value), committing ONE undoable
SetDrumVelocityCmd on release via the revert-then-exec finalize pattern.
- Shift+Up/Down nudges the selection +/-10; A / N quick-set accent (115) /
normal (100). Claimed inside drum-edit mode only, where those keys
otherwise no-op against the empty note selection.
- SetDrumVelocityCmd restores authored dynamics verbatim on undo — a hit
with no explicit v gets the field DELETED again, not set to 100.
- The G ghost toggle pulls a normal-strength hit to the ghost velocity
(35; import derives g from v<40) instead of authoring a contradictory
ghost at v:100. Already-quiet hits keep their dynamics; un-ghost leaves
v untouched; ToggleDrumArticulationCmd('g') snapshots {had, v} and
restores both exactly (f/k stay involutive).
- XS fix: the unmapped-notes import dialog no longer flattens dynamics —
routes.py passes an optional velocities array (index-aligned with times,
filtered in lockstep) and the modal carries real source velocities
through instead of pushing v:100. Older cores omit the field cleanly.
Tests: tests/drum_velocity.test.js (11 cases, real commands over the
extracted blocks — the ghost-pull and authoring assertions fail on main).
Full JS suite 42 files + pytest 191 passed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JEoFeTPSnz4NpwwCG52hnu
3b81d21 to
0cd2bdb
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
- SetDrumVelocityCmd: clear a stale g (ghost) flag when velocity is
raised above the ghost band (Accent / Shift+Up / Alt-drag up), so an
edit can no longer author a contradictory loud ghost; snapshot + restore
the {g, v} pair symmetrically on undo/redo (CodeRabbit).
- Import: hand-mapped unmapped notes now derive g from carried velocity
(g <= v < 40) via a new pure _drumImportHitPure helper, matching the
MIDI importer so a quiet hand-mapped note renders/round-trips as a ghost
identically to the normal path (Codex).
- Regression tests in tests/drum_velocity.test.js for both paths (fail
pre-fix). Full JS suite 48/48 green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@coderabbitai review |
✅ Action performedReview finished.
|
Roadmap 4.5 (Phase 4 — drums). Velocity always rendered (brightness/height) and imported from MIDI, but authoring wrote a hardcoded
v:100with no way to change it. Drum undo (#89) unblocked this.What
SetDrumVelocityCmdvia the same revert-then-exec finalize pattern asMoveDrumHitsCmd. Mode switches mid-drag finalize through_finalizeActiveDrag.SetDrumVelocityCmdrestores authored dynamics verbatim on undo — a hit that had no explicitvgets the field deleted again, not set to 100. Inputs clamp to MIDI 1–127 at the command boundary.gfromv < 40, so it round-trips as a ghost) instead of authoring a contradictory ghost atv:100. Already-quiet hits keep their authored dynamics; un-ghosting leaves velocity untouched;ToggleDrumArticulationCmd(''g'')snapshots{had, v}per hit and restores both exactly on undo.f/kstay involutive.v:100, flattening real dynamics.routes.pynow passes an optionalvelocitiesarray (index-aligned withtimes, filtered in lockstep so a dropped bad time drops its velocity) and the modal carries source velocities through. Older cores that don''t capture velocities simply omit the field — the 100 default is unchanged. A tiny additive core PR can light this up end-to-end (the capture site inlib/midi_import.pyhasmsg.velocityin hand).Tests
tests/drum_velocity.test.js(11 cases) drives the real command classes over the extracted@pure:drum-cmds+@pure:edit-historyblocks: clamp/drag pure math, exact-restore undo (including delete-not-100), scalar broadcast, ghost pull + mixed-state round-trips, and f/k involution regression. The authoring and ghost-pull assertions fail on main. Full JS suite: 42 files green; pytest: 191 passed;node --checkclean.Fresh region vs the open queue (#101–#108) — drum editor interaction + the unmapped-import shaping only.
🤖 Generated with Claude Code
https://claude.ai/code/session_01JEoFeTPSnz4NpwwCG52hnu
Summary by CodeRabbit
New Features
Bug Fixes
Tests