fix(editor): a multi-drum Guitar Pro import keeps each drummer separate#355
Conversation
|
Warning Review limit reached
Next review available in: 20 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 (7)
📝 WalkthroughWalkthroughGP imports now preserve multiple drum tracks as separate drum parts when pitched arrangements exist. Backend conversion returns primary, extra, and unmapped drum data; create-mode loading materializes extra parts through ChangesGP multidrum import
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant GPFile
participant convert_gp
participant editorApplyCreateResult
participant adoptDrumParts
participant EditorState
GPFile->>convert_gp: import multiple drum tracks
convert_gp-->>editorApplyCreateResult: drum_tab and drum_parts
editorApplyCreateResult->>EditorState: sync primary drum arrangement
editorApplyCreateResult->>adoptDrumParts: pass data.drum_parts
adoptDrumParts->>EditorState: create additional drums parts
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 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 `@routes.py`:
- Around line 308-317: Update the drum-track import flow around with_hits and
the unmapped return path so unmapped notes retain their originating tab instead
of being aggregated into the single primary drum tab. Materialize or target each
unmapped source tab during frontend mapping while preserving mapped-track
behavior, and add a regression test covering mixed mapped and unmapped drum
tracks.
🪄 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: 51bb58f6-c675-49f7-82c7-f69daf99c7f1
📒 Files selected for processing (5)
CHANGELOG.mdroutes.pysrc/create.jstests/create_drum_materialize.test.jstests/test_gp_multidrum_split.py
The Create-New Guitar Pro import folded EVERY drum track into one `drum_tab` (`_drum_arrs_to_drum_tab([all of them])`), so a song with a second drummer or an aux-percussion layer came in as a single squashed drum part — the drums-as-plural work already shipped, but this one path still collapsed them. It now keeps each drum track as its own `type:"drums"` part: one drum_tab per drum arrangement (the GP track name preserved), the first as the primary (song-level `drum_tab` back-compat alias) and the rest as `drum_parts` — the exact shape a reload adopts (`adoptDrumParts`) and `/build` persists. A single drum track, or a drums-only import (which can't hold plural parts — a drums arrangement never sits at index 0), still folds into one, so those imports stay byte-identical. The split is a new module-level `_gp_drum_arrs_to_parts` (mirrors the testable `_drum_arrs_to_drum_tab`); the frontend adopts the extras through the existing load-time `adoptDrumParts`. This brings the GP create-import to parity with the MIDI drum auto-split. Tests: tests/test_gp_multidrum_split.py (7 cases: split vs fold, the drums-only fold, empty-track drop, all-unmapped recovery tab, name preservation/cap) + the structural wiring pins in create_drum_materialize.test.js (adopt runs after the primary is materialized, guarded on a non-empty drum_parts). Full pytest green (388); lint clean; only the two known-on-main JS reds (mixer_meter_teardown, song_fit). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017xGPjDBF8NTwTK7VQvizix Signed-off-by: ChrisBeWithYou <chris@rifflarr.local>
a937d25 to
9ee3581
Compare
The bug
The Create-New Guitar Pro import folded every drum track into a single
drum_tab(_drum_arrs_to_drum_tab([all of them])). So a song with a second drummer, or a kit + an aux-percussion layer, arrived as one squashed drum part — the drums-as-plural infrastructure already shipped (#336–#339), but this one import path still collapsed them.The fix
Keep each GP drum track as its own
type:"drums"part:drum_tabper drum arrangement, with the GP track name preserved;drum_tabback-compat alias);drum_parts— the exact shape a reload adopts (adoptDrumParts) and/buildalready persists.A single drum track, or a drums-only import (which can't hold plural parts — a drums arrangement never sits at index 0, so there's no melodic sibling to materialize beside), still folds into one tab, so those imports stay byte-identical to before.
The split decision is a new module-level
_gp_drum_arrs_to_parts(mirroring the already-testable_drum_arrs_to_drum_tab), and the frontend materializes the extras through the existing load-timeadoptDrumParts— the same path a saved multi-drum song uses on reopen. This brings the GP create-import to parity with the MIDI drum auto-split.Scope
The natural sibling of the MIDI drum work. Together they close the "a full-band import shouldn't lose or squash its drums" gap for both formats. The remaining drum residual (re-typing a pitched arrangement to/from drums) is a separate, design-heavy item left untouched.
Tests
tests/test_gp_multidrum_split.py(7 cases) pins the split helper: several tracks + a melodic part → primary +drum_partswith names preserved; a single track folds; a drums-only import folds even with several tracks; an empty leading track is dropped and the primary is the first with hits; an all-unmapped import keeps one empty tab so the manual-mapping dialog can recover it; nothing-to-keep returnsNone; GP track names preserved and length-capped.create_drum_materialize.test.jsextended (the established structural pattern for the DOM-heavyeditorApplyCreateResult):adoptDrumPartsis imported and called aftersyncDrumArrangement(extras append beside the materialized primary), guarded on a non-emptydata.drum_parts.mainreds (mixer_meter_teardown,song_fit).Verification note: the split logic is unit-tested against the fake-core GM table, and the frontend reuses the already-proven
adoptDrumPartsload path + thedrum_partsbuild persistence — a real binary multi-drum.gpend-to-end wasn't synthesized (impractical to hand-author), so the coverage is the pure helper + the reused-and-tested adoption/persistence path rather than a live GP import.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes