fix(gp): GP6/GPIF note strings are 0-indexed (correct pitch, recover dropped notes) - #62
Conversation
The guitarpro crate exposes a note's `string` field 0-indexed for GP6/GPIF
(.gpx) but 1-indexed for the GP3/4/5 binary readers — the same per-format
divergence already handled for repeat counts. gp_note_midi_pitch and
gp_note_position assumed 1-indexing unconditionally, so every GP6 note read
the open tuning of the string one position too low (≈4–5 semitones flat),
and every note on raw string 0 (the lowest string) was rejected by the
`string <= 0` guard as "pitch out of range".
Normalise the raw string to griff's 1-indexed convention per source format
via gp_one_indexed_string(raw, zero_indexed), threaded from gp_song_to_score
(version_major >= 6) down through a small read-only StringCtx. The GP3/4/5
binary path is unchanged.
Verified on a real drop-D .gpx: pitch ranges and pitch-class sets now match
Guitar Pro's own MIDI export exactly (track 0: 41-77, track 1: 38-84, both
{0,2,3,5,7,9,10}), and the ~140 dropped low-string notes are recovered (zero
"out of range" losses).
Tests: gp6_strings_are_zero_indexed, gp6_note_position_normalises_string_number,
and gp_one_indexed_string_normalises_per_format pin the convention; existing
binary-path pitch/position tests pass unchanged.
https://claude.ai/code/session_01TTUbGjzD8ysnVnCJnZJE95
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough
ChangesGP String Index Normalization
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Problem
A Guitar Pro 6 (
.gpx) import came out ≈4–5 semitones flat with notesmissing — most audible as "everything shifted down" and a thinned-out low riff.
Root cause
The
guitarprocrate exposes a note'sstringfield 0-indexed for theGP6/GPIF reader, but 1-indexed for the GP3/4/5 binary readers — the same
per-format divergence griff already normalises for repeat counts
(
version_major >= 6).gp_note_midi_pitch/gp_note_positionassumed 1-indexing unconditionally(
strings[note.string - 1], plus anote.string <= 0reject). For GP6 that:transposed down by that string interval (~4–5 semitones); and
<= 0guard, logged as "GP note pitch out of range; note skipped".
Evidence (raw crate data for the reported drop-D
.gpx)Track::strings = [(1,38),(2,45),(3,50),(4,55),(5,59),(6,64)], notes carrystring ∈ 0..5. Brute-forcing the index against Guitar Pro's own MIDI exportof the same file: only
strings[note.string](0-indexed) reproduces thereference pitch set — e.g. lead bar 1 →
{51,58,62,65,67,77,79}, exact match;the old
strings[note.string-1]gave{44,53,57,60,62,72,74}.Fix
Normalise the raw string to griff's 1-indexed convention per source format:
zero_indexed = version_major >= 6is derived ingp_song_to_score(next to theexisting repeat-count split) and threaded down through a small read-only
StringCtx { strings, zero_indexed }. The GP3/4/5 binary path is byte-for-byteunchanged (
zero_indexed = false).Verification (real
.gpx, through the publicimport_gp_scorepath){0,2,3,5,7,9,10}{0,2,3,5,7,9,10}{0,2,3,5,7,9,10}{0,2,3,5,7,9,10}Ranges and pitch-class sets now match Guitar Pro's own export exactly, and the
~140 dropped low-string notes are recovered (0 "out of range" losses, was ~140).
Tests
gp6_strings_are_zero_indexed— raw string 0 maps to the first entry (notdropped); raw string 1 + fret 6 = 51 (not 44).
gp6_note_position_normalises_string_number— raw 0 → griff string 1.gp_one_indexed_string_normalises_per_format— both bases., false).Full workspace suite +
clippy --all-targetsclean.gp.rsis rustfmt-clean(two unrelated pre-existing
dump.rs/dump_golden.rsrustfmt diffs leftuntouched — they predate this branch).
Second of the two fixes for the reported issues; the MIDI Type-0 export fix is
#61. With clean GP6 input, the complement "low copy" observation is worth a
fresh look — happy to follow up.
https://claude.ai/code/session_01TTUbGjzD8ysnVnCJnZJE95
Generated by Claude Code
Summary by CodeRabbit