`GP3File.readNote` never read flag bits 0x02 (heavy accent) and 0x40
(normal accent) from the note flags byte, even though the docstring
documented them. GP4 inherited this broken read path; only GP5 read
them correctly.
The writer side was asymmetric too: `GP3File.packNoteFlags` emitted
0x02 but not 0x40, while GP4 overrode it to add 0x40 only. Round-tripping
a note with `accentuatedNote=True` through PGP silently dropped the flag.
This change:
* reads both flags in `GP3File.readNote` (inherited by GP4)
* writes flag 0x40 in `GP3File.packNoteFlags`
* drops the now-redundant override in `GP4File.packNoteFlags`
* adds a round-trip regression test for all three formats
Cross-checked against alphaTab's `Gp3To5Importer.ts:1203-1207` which
extracts both flags universally.
Closes #1
Bug
GP3File.readNotenever reads flag bits0x02(heavy accent) and0x40(normal accent) from the note flags byte, even though the docstring atgp3.py:870-879documents both flags. GP4 inherits this broken read path; only GP5 reads them correctly.The writer side is asymmetric:
GP3File.packNoteFlagsemits0x02but not0x40GP4File.packNoteFlagsoverrides to add0x40onlyRound-tripping a note with
accentuatedNote=Truethrough PGP silently drops the flag.Reference: alphaTab
alphaTab's
Gp3To5Importer.ts:1210-1217shows the canonical read path for both flags:Fix
GP3File.readNote: read both flags 0x02 and 0x40 (mirroring AT)GP3File.packNoteFlags: write 0x40 alongside existing 0x02GP4File.packNoteFlags: drop the now-redundant 0x40 override (superseded by gp3)Verification
Added
testNoteAccentuationRoundtripintests/test_conversion.py, parametrised over GP3/GP4/GP5 fixtures. Verifies bothaccentuatedNoteandheavyAccentuatedNotesurvive a write→read cycle.Without the fix:
Effects.gp3fails (accentuatedNote not preserved on round-trip)Effects.gp4fails (same)Effects.gp5passes (already worked correctly)With the fix: 3/3 tests pass.
All 195 existing tests continue to pass.