Repository navigation
fix: spell MusicXML notes from step/alter, export spellings correctly to Guitar Pro and alphaTex - #2931
Merged
Conversation
Adds ModelUtils.simplifyAccidentalMode which reduces a forced accidental mode to Default when it resolves to the spelling Default would choose anyhow. Exporters can use it to only write the hints that matter.
The ConcertPitch/TransposedPitch step was taken from a fixed sharp table and the accidental from the sign needed in the key, which wrote wrong pitches in many keys (e.g. Bb in F major as A or Ab). Write the resolved spelling instead, with the octave belonging to the step as Guitar Pro does. Round trip tests now compare the accidental modes which matter for the rendering instead of ignoring them.
…spelling Formats like Guitar Pro store the spelling on every note, which resulted in an acc property on nearly every exported note. Only write the hints which result in a different spelling than the default one.
The spelling of a note is defined by <step> and <alter>, <accidental> only describes the printed sign. Notes without printed sign (repeated in a bar, tied over a bar line) were spelled from the key signature instead, e.g. F# as Gb in flat keys. Signs contradicting the pitch are reported.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
AI-authored disclosure (
alphatab-ai-authored-v1)Portions of this content were authored by an AI agent. The agent has read
AGENTS.md and the human submitter accepts responsibility for
compliance with the rules in that document.
Issues
Fixes #2861
Proposed changes
Root cause: the MusicXML importer turned
<step>/<alter>into a plain semitone value. Only<accidental>set
Note.accidentalMode, which holds the note's spelling. Notes without a printed sign (repeated in a bar, ortied over a bar line) were therefore spelled from the key signature: F# became Gb in flat keys, and B became Cb
in Gb major. A tie then connected two different staff lines.
In MusicXML the spelling is defined by
<pitch>, and<accidental>only describes the printed sign. MuseScore(
step2tpc(step, alter)) and Verovio (pnamefrom<step>) both work this way.Importer:
accidentalModeis now set from<alter>(0 → ForceNatural, ±1 → ForceSharp/ForceFlat,±2 → ForceDoubleSharp/ForceDoubleFlat). This is the same model the Guitar Pro 7 importer already produces.
An
<accidental>that contradicts the pitch only logs a warning; the pitch wins.The
Force*modes only choose among spellings of the same pitch; the printed sign is still worked out from thebar. So a forced mode can never move a note to a wrong pitch. This was checked over every key × step × alter
(−2..+2) × octave × clef combination.
Setting the spelling on every note affects both exporters, so they are fixed here as well:
GpifWritertook thePitchstep from a fixed sharp table and the accidental from thesign needed in the key. That wrote wrong pitch spellings in many keys, in Default and forced modes alike (e.g.
Bb in F major became "A" or "Ab"). It now writes the resolved spelling. The octave belongs to the letter, as in
Guitar Pro's own files (B#4 = MIDI 60, Cb5 = MIDI 59). Exporting GP-authored test files now reproduces their
TransposedPitchexactly (0 differences, previously 755 of 2085 notes). Opening the exported files in GuitarPro shows the same note placement and accidentals as alphaTab.
{acc …}was written for nearly every note coming from Guitar Pro, and would have beenfor MusicXML too. A new
ModelUtils.simplifyAccidentalModereduces a hint toDefaultwhen it gives the samespelling as the default. Rendering only reads the mode through
resolveSpellingand theForceNonechecks, sodropping such hints cannot change the output. The exporter now only writes hints that change the spelling.
Across the test data this cuts the
accproperties from 23,901 to 1,387, with identical rendering after analphaTex round trip.
accidentalmode.Reference changes (all reviewed): MusicXML samples and test-suite files now follow the source spelling.
Examples: Dichterliebe bar 27 had this issue's tie bug; Debussy, Schubert and Brahms lose wrong enharmonic
swaps; 13a now renders C♮ in C# major instead of B#. The MusicXML snapshots gain
accidentalmodevalues, andthe alphaTex formatted reference loses redundant
accproperties.Out of scope:
accidentalModeis spelling only)Checklist
AI authorship disclosure
(
alphatab-ai-authored-v1) is present at the top of this body, and I havepersonally reviewed every change and can explain each one
Further details