Skip to content

fix(editor): a multi-drum Guitar Pro import keeps each drummer separate#355

Merged
ChrisBeWithYou merged 3 commits into
mainfrom
feat/gp-multidrum-split
Jul 22, 2026
Merged

fix(editor): a multi-drum Guitar Pro import keeps each drummer separate#355
ChrisBeWithYou merged 3 commits into
mainfrom
feat/gp-multidrum-split

Conversation

@ChrisBeWithYou

@ChrisBeWithYou ChrisBeWithYou commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

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:

  • one drum_tab per drum arrangement, with the GP track name preserved;
  • the first non-empty is the primary (the song-level drum_tab back-compat alias);
  • the rest ride as drum_parts — the exact shape a reload adopts (adoptDrumParts) and /build already 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-time adoptDrumParts — 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_parts with 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 returns None; GP track names preserved and length-capped.
  • create_drum_materialize.test.js extended (the established structural pattern for the DOM-heavy editorApplyCreateResult): adoptDrumParts is imported and called after syncDrumArrangement (extras append beside the materialized primary), guarded on a non-empty data.drum_parts.
  • Full pytest green (388 passed, 5 skipped); lint clean; JS suite unchanged apart from the two known-on-main reds (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 adoptDrumParts load path + the drum_parts build persistence — a real binary multi-drum .gp end-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

    • Guitar Pro imports now preserve multiple drum tracks as separate drum parts when a melodic part is present.
    • Drum track names are retained, and unmapped MIDI hits remain available for manual mapping.
  • Bug Fixes

    • Prevented multiple GP drum tracks from being incorrectly merged into one drum tab.
    • Preserved existing single-tab behavior for imports that cannot support multiple drum parts.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ChrisBeWithYou, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 20 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9c58484a-f709-4ed7-ab6f-2fcf23b51b69

📥 Commits

Reviewing files that changed from the base of the PR and between 94d10b7 and 9ee3581.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • routes.py
  • src/create.js
  • src/import.js
  • tests/create_drum_materialize.test.js
  • tests/drum_arrangement.test.mjs
  • tests/test_gp_multidrum_split.py
📝 Walkthrough

Walkthrough

GP 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 adoptDrumParts, with regression coverage for splitting, folding, and edge cases.

Changes

GP multidrum import

Layer / File(s) Summary
Drum arrangement conversion and edge cases
routes.py, tests/test_gp_multidrum_split.py
Adds _gp_drum_arrs_to_parts to split drum arrangements with pitched content, fold them otherwise, preserve names, and report unmapped MIDI hits. Tests cover primary selection, empty and unmapped tracks, folding, and name limits.
GP conversion response
routes.py
Updates convert_gp to emit drum_tab, drum_parts, and drum_unmapped, while retaining only pitched arrangements in arrangements.
Create-mode materialization
src/create.js, tests/create_drum_materialize.test.js, CHANGELOG.md
Adopts non-empty data.drum_parts after synchronizing the primary drum arrangement, with frontend assertions and a changelog entry documenting the behavior.

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
Loading

Suggested reviewers: byrongamatos

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: multi-drum Guitar Pro imports now keep each drum track separate.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/gp-multidrum-split

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between ba4f924 and 94d10b7.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • routes.py
  • src/create.js
  • tests/create_drum_materialize.test.js
  • tests/test_gp_multidrum_split.py

Comment thread routes.py Outdated
ChrisBeWithYou and others added 3 commits July 22, 2026 17:58
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>
@ChrisBeWithYou
ChrisBeWithYou force-pushed the feat/gp-multidrum-split branch from a937d25 to 9ee3581 Compare July 22, 2026 22:59
@ChrisBeWithYou
ChrisBeWithYou merged commit e217c91 into main Jul 22, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant