musescore / musescore/MuseScore

MEI 5.1 import drops quarter-tone accidental semantics and cent offsets

Open
#34,567 0 comments 0 reactions 1 assignee View on GitHub

@rasalinga is already working on this.

Since Aug 18, 2026.

community MEI
Dominant language
C++
Stars
15.1k
Forks
3.3k
Avg merge
2d 2h
Merged PRs (30d)
91

Description

Issue type

Import/export issue (MEI)

Description

MuseScore Studio 4.7.4 does not preserve legal MEI 5.1 microtonal written accidentals such as 1qs and 3qs. Import reports that it cannot convert the pitch and accidental, then falls back to a natural/integer-semitone representation. This loses both the written accidental identity and its sounding cent displacement.

The same warning path also affects command-line import: when warnings are produced, the importer opens a synchronous confirmation dialog. In a headless invocation the dialog is not visible, so the process can remain waiting instead of producing the requested output.

A source audit of the current development branch at d874179942701066fd249c0e5649be53fa7600e4 found the same conversion path. A candidate fix has been ported and tested against that revision.

Steps to reproduce

  1. Save the following as microtonal-roundtrip.mei.
  2. Open it in MuseScore Studio 4.7.4, or import it with MuseScore4.exe -o microtonal-roundtrip.mscz microtonal-roundtrip.mei.
  3. Observe the conversion warnings for the microtonal notes.
  4. If import is continued in the GUI, save and export the score as MEI.
  5. Compare the written accidentals and sounding alterations with the input.
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/5.1/mei-basic.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.1+basic">
   <meiHead>
      <fileDesc>
         <titleStmt>
            <title>MEI microtonal round-trip regression</title>
         </titleStmt>
         <pubStmt>
            <date isodate="2026-08-13" />
         </pubStmt>
      </fileDesc>
   </meiHead>
   <music>
      <body>
         <mdiv>
            <score>
               <scoreDef>
                  <staffGrp>
                     <staffDef n="1" lines="5" meter.count="4" meter.unit="4">
                        <label>Voice</label>
                        <labelAbbr>Vo.</labelAbbr>
                        <clef shape="G" line="2" />
                     </staffDef>
                  </staffGrp>
               </scoreDef>
               <section>
                  <measure n="1">
                     <staff n="1">
                        <layer n="1">
                           <note dur="4" pname="c" oct="4"><accid accid="s" /></note>
                           <note dur="4" pname="d" oct="4"><accid accid="1qs" /></note>
                           <note dur="4" pname="e" oct="4"><accid accid="3qs" /></note>
                           <note dur="4" pname="f" oct="4"><accid accid="sd" /></note>
                        </layer>
                     </staff>
                  </measure>
                  <measure n="2" right="end">
                     <staff n="1">
                        <layer n="1">
                           <note dur="4" pname="g" oct="4"><accid accid="su" /></note>
                           <rest dur="2" />
                           <rest dur="4" />
                        </layer>
                     </staff>
                  </measure>
               </section>
            </score>
         </mdiv>
      </body>
   </music>
</mei>

Actual behavior

  • 1qs, 3qs, sd, and su generate pitch/accidental conversion warnings.
  • Import falls back to a natural/integer-semitone representation.
  • Exact written identity and fractional sounding displacement are not available to the exporter.
  • A headless import can wait on the synchronous warning dialog without producing an MSCZ file.

Expected behavior

  • 1qs imports as a quarter-tone sharp with a +50 cent sounding displacement and exports as 1qs.
  • 3qs imports as a three-quarter-tone sharp with a +150 cent sounding displacement and exports as 3qs.
  • The equivalent arrow forms preserve the same semantics (sd = +50 cents, su = +150 cents).
  • Representable legal microtonal values import without a fallback warning.
  • Command-line import does not block on warnings caused by these supported values.

Root cause

Convert::accidFromMEI() handles ordinary written accidentals but sends unhandled legal microtonal tokens through a warning path that returns AccidentalType::NATURAL. The pitch transport carries only an integer accidental alteration, so a fractional cent component cannot reach engraving::Note. Export therefore cannot reconstruct the original written token.

The hand-maintained libmei::Att::AccidentalWrittenToGestural() mapping also reverses the quarter-tone sharp derivations: 1qs is mapped to the +150-cent form and 3qs to the +50-cent form.

Version and environment

  • Reproduced application: MuseScore Studio 4.7.4, revision 7688c005ad963ba09ee715aae53dbc7e8c9d5ef8
  • Source path also audited on current main, revision d874179942701066fd249c0e5649be53fa7600e4
  • MEI: 5.1 Basic
  • OS: Windows 11 x64
  • Regression status: unable to determine

Testable acceptance result

The reproducer imports without accidental-conversion warnings; the native score retains the distinct accidental types and +50/+150 cent offsets; exporting the unedited native score returns 1qs, 3qs, sd, and su with unchanged sounding semantics.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.