Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The issue of missing audio effects. #3775

Open
Dahurica opened this issue Sep 14, 2024 · 9 comments
Open

The issue of missing audio effects. #3775

Dahurica opened this issue Sep 14, 2024 · 9 comments

Comments

@Dahurica
Copy link

Hello,

The currently generated MIDI file has incorrect durations for grace notes, and there are no playback effects for mordents, trills, turns, and inverted turns. Could you please advise on where I can make changes to include the logic for these elements in the generated MIDI?

Thank you!

Here is my XML:
   <measure number="1">
      <attributes>
        <divisions>60</divisions>
        <key>
          <fifths>0</fifths>
          </key>
        <time>
          <beats>4</beats>
          <beat-type>4</beat-type>
          </time>
        <staves>2</staves>
        <clef number="1">
          <sign>G</sign>
          <line>2</line>
          </clef>
        <clef number="2">
          <sign>F</sign>
          <line>4</line>
          </clef>
        </attributes>
      <direction placement="above">
        <direction-type>
          <words font-weight="bold" font-size="12">Grave</words>
          </direction-type>
        <staff>1</staff>
        <sound tempo="35"/>
        </direction>
      <direction placement="below">
        <direction-type>
          <pedal type="resume" line="yes" sign="yes"/>
          </direction-type>
        <staff>1</staff>
        </direction>
      <note>
        <pitch>
          <step>D</step>
          <octave>5</octave>
          </pitch>
        <duration>60</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note>
        <pitch>
          <step>C</step>
          <octave>5</octave>
          </pitch>
        <duration>60</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note>
        <pitch>
          <step>C</step>
          <octave>5</octave>
          </pitch>
        <duration>60</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note>
        <pitch>
          <step>C</step>
          <octave>5</octave>
          </pitch>
        <duration>60</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <direction placement="below">
        <direction-type>
          <pedal type="stop" line="yes" sign="no"/>
          </direction-type>
        <staff>1</staff>
        </direction>
      <backup>
        <duration>240</duration>
        </backup>
      <note>
        <grace/>
        <pitch>
          <step>C</step>
          <octave>5</octave>
          </pitch>
        <voice>2</voice>
        <type>32nd</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">begin</beam>
        <beam number="2">begin</beam>
        <beam number="3">forward hook</beam>
        </note>
      <note>
        <grace/>
        <pitch>
          <step>C</step>
          <octave>5</octave>
          </pitch>
        <voice>2</voice>
        <type>16th</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">continue</beam>
        <beam number="2">end</beam>
        </note>
      <note>
        <grace slash="yes"/>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <voice>2</voice>
        <type>eighth</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">end</beam>
        </note>
      <note>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <duration>60</duration>
        <voice>2</voice>
        <type>quarter</type>
        <stem>down</stem>
        <staff>1</staff>
        </note>
      <note>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <duration>60</duration>
        <voice>2</voice>
        <type>quarter</type>
        <stem>down</stem>
        <staff>1</staff>
        </note>
      <note>
        <grace/>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <voice>2</voice>
        <type>32nd</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">begin</beam>
        <beam number="2">begin</beam>
        <beam number="3">begin</beam>
        </note>
      <note>
        <grace/>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <voice>2</voice>
        <type>32nd</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">end</beam>
        <beam number="2">end</beam>
        <beam number="3">end</beam>
        </note>
      <note>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <duration>60</duration>
        <voice>2</voice>
        <type>quarter</type>
        <stem>down</stem>
        <staff>1</staff>
        </note>
      <note>
        <grace/>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <voice>2</voice>
        <type>eighth</type>
        <stem>down</stem>
        <staff>1</staff>
        </note>
      <note>
        <pitch>
          <step>F</step>
          <octave>4</octave>
          </pitch>
        <duration>60</duration>
        <voice>2</voice>
        <type>quarter</type>
        <stem>down</stem>
        <staff>1</staff>
        </note>
      <backup>
        <duration>240</duration>
        </backup>
      <note>
        <rest measure="yes"/>
        <duration>240</duration>
        <voice>5</voice>
        <staff>2</staff>
        </note>
      <barline location="right">
        <bar-style>light-light</bar-style>
        </barline>
      </measure>
    <measure number="2">
      <direction placement="above">
        <direction-type>
          <words font-weight="bold" font-size="12">Largo</words>
          </direction-type>
        <staff>1</staff>
        <sound tempo="50"/>
        </direction>
      <direction placement="below">
        <direction-type>
          <dynamics>
            <p/>
            </dynamics>
          </direction-type>
        <staff>1</staff>
        <sound dynamics="54.44"/>
        </direction>
      <direction placement="below">
        <direction-type>
          <pedal type="resume" line="yes" sign="yes"/>
          </direction-type>
        <staff>1</staff>
        </direction>
      <note>
        <pitch>
          <step>C</step>
          <octave>5</octave>
          </pitch>
        <duration>120</duration>
        <voice>1</voice>
        <type>whole</type>
        <time-modification>
          <actual-notes>2</actual-notes>
          <normal-notes>1</normal-notes>
          </time-modification>
        <staff>1</staff>
        <notations>
          <ornaments>
            <tremolo type="start">3</tremolo>
            </ornaments>
          </notations>
        </note>
      <note>
        <pitch>
          <step>A</step>
          <octave>4</octave>
          </pitch>
        <duration>120</duration>
        <voice>1</voice>
        <type>whole</type>
        <time-modification>
          <actual-notes>2</actual-notes>
          <normal-notes>1</normal-notes>
          </time-modification>
        <staff>1</staff>
        <notations>
          <ornaments>
            <tremolo type="stop">3</tremolo>
            </ornaments>
          </notations>
        </note>
      <direction placement="below">
        <direction-type>
          <pedal type="stop" line="yes" sign="no"/>
          </direction-type>
        <staff>1</staff>
        </direction>
      <backup>
        <duration>240</duration>
        </backup>
      <note>
        <pitch>
          <step>E</step>
          <octave>3</octave>
          </pitch>
        <duration>120</duration>
        <voice>5</voice>
        <type>whole</type>
        <time-modification>
          <actual-notes>2</actual-notes>
          <normal-notes>1</normal-notes>
          </time-modification>
        <staff>2</staff>
        <notations>
          <ornaments>
            <tremolo type="start">1</tremolo>
            </ornaments>
          </notations>
        </note>
      <note>
        <pitch>
          <step>C</step>
          <octave>3</octave>
          </pitch>
        <duration>120</duration>
        <voice>5</voice>
        <type>whole</type>
        <time-modification>
          <actual-notes>2</actual-notes>
          <normal-notes>1</normal-notes>
          </time-modification>
        <staff>2</staff>
        <notations>
          <ornaments>
            <tremolo type="stop">1</tremolo>
            </ornaments>
          </notations>
        </note>
      <barline location="right">
        <bar-style>light-heavy</bar-style>
        <repeat direction="backward"/>
        </barline>
      </measure>
    <measure number="3">
      <barline location="left">
        <bar-style>heavy-light</bar-style>
        <repeat direction="forward"/>
        </barline>
      <direction placement="above">
        <direction-type>
          <words font-weight="bold" font-size="12">Lento</words>
          </direction-type>
        <staff>1</staff>
        <sound tempo="52.5"/>
        </direction>
      <direction placement="below">
        <direction-type>
          <dynamics>
            <mp/>
            </dynamics>
          </direction-type>
        <staff>1</staff>
        <sound dynamics="71.11"/>
        </direction>
      <note>
        <pitch>
          <step>B</step>
          <octave>4</octave>
          </pitch>
        <duration>120</duration>
        <voice>1</voice>
        <type>half</type>
        <stem>down</stem>
        <staff>1</staff>
        <notations>
          <ornaments>
            <tremolo type="single">3</tremolo>
            </ornaments>
          </notations>
        </note>
      <note>
        <pitch>
          <step>G</step>
          <octave>4</octave>
          </pitch>
        <duration>120</duration>
        <voice>1</voice>
        <type>half</type>
        <stem>up</stem>
        <staff>1</staff>
        <notations>
          <ornaments>
            <tremolo type="single">3</tremolo>
            </ornaments>
          </notations>
        </note>
      <backup>
        <duration>240</duration>
        </backup>
      <note>
        <pitch>
          <step>E</step>
          <octave>3</octave>
          </pitch>
        <duration>120</duration>
        <voice>5</voice>
        <type>half</type>
        <stem>down</stem>
        <staff>2</staff>
        <notations>
          <ornaments>
            <tremolo type="single">2</tremolo>
            </ornaments>
          </notations>
        </note>
      <note>
        <pitch>
          <step>D</step>
          <octave>3</octave>
          </pitch>
        <duration>120</duration>
        <voice>5</voice>
        <type>half</type>
        <stem>down</stem>
        <staff>2</staff>
        <notations>
          <ornaments>
            <tremolo type="single">2</tremolo>
            </ornaments>
          </notations>
        </note>
      </measure>

In the first measure, there is an issue with the grace note playback. At standard tempo, it might be inaudible, making it seem like there is no sound

@craigsapp
Copy link
Contributor

craigsapp commented Sep 14, 2024

A request for mordents, trills, turn, etc for MIDI export has an issue already: #1928

Algorithms that take tempo (and note score-based durations) are needed in order to realize mordents, trills, and turns (and to some extent for grace notes). If there are published algorithms for generating ornaments, this it is more likely that these ornaments will be added to verovio. I.e., at tempo 100, how should auxiliary notes for a mordent on a quarter note be realized, at a tempo of 180 on an 8th note?, etc. Providing such algorithms would make it more likely to be implement in verovio.

Do you mean where in the C++ code to add for a PR? @lpugin could answer that. Basically in src/midifunctor.cpp.

There have been other samplers of ornaments to realize in MIDI in the past week:
#3754
#3770

The MusicXML excerpt is nice, but preferably a complete file is desired (that can be loaded into verovio, since an excerpt cannot be loaded). Otherwise, nothing can be down with the excerpt, such as check to see if there is a problem in the MusicXML import as compared to grace notes in the MEI form of the data.

grace notes do note have a duration, so it cannot be wrong :-)

        <grace/>
        <pitch>
          <step>C</step>
          <octave>5</octave>
          </pitch>
        <voice>2</voice>
        <type>32nd</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">begin</beam>
        <beam number="2">begin</beam>
        <beam number="3">forward hook</beam>
        </note>

GenerateMIDIFunctor::GenerateGraceNoteMIDI() in src/midifunctor.cpp is used to add grace notes to MIDI:

void GenerateMIDIFunctor::GenerateGraceNoteMIDI(
    const Note *refNote, double startTime, int tpq, int channel, int velocity)
{
    double graceNoteDur = 0.0;
    if (m_accentedGraceNote && !m_graceNotes.empty()) {
        const double totalDur = refNote->GetScoreTimeDuration() / 2.0;
        this->DeferMIDINote(refNote, totalDur, true);
        graceNoteDur = totalDur / m_graceNotes.size();
    }
    else {
        graceNoteDur = UNACC_GRACENOTE_DUR * m_currentTempo / 60000.0;
        const double totalDur = graceNoteDur * m_graceNotes.size();
        if (startTime >= totalDur) {
            startTime -= totalDur;
        }
        else {
            this->DeferMIDINote(refNote, totalDur, true);
        }
    }

    for (const MIDIChord &chord : m_graceNotes) {
        const double stopTime = startTime + graceNoteDur;
        for (int pitch : chord.pitches) {
            m_midiFile->addNoteOn(m_midiTrack, startTime * tpq, channel, pitch, velocity);
            m_midiFile->addNoteOff(m_midiTrack, stopTime * tpq, channel, pitch);
        }
        startTime = stopTime;
    }
}

Line 75 of include/vrv/vrv.h has the definition of the duration of a grace note which seems to be 27 milliseconds:

 #define UNACC_GRACENOTE_DUR 27 // in milliseconds

@craigsapp
Copy link
Contributor

Note that there are two types of grace notes in MEI: accacciaturas rendered with slashes and appoggiaturas redered without slashes:

Screenshot 2024-09-13 at 8 04 13 PM
Click to view MEI data for above example.
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0">
 <meiHead>
  <fileDesc>
   <titleStmt>
    <title />
   </titleStmt>
   <pubStmt>
   </pubStmt>
  </fileDesc>
  <encodingDesc>
   <appInfo>
    <application isodate="2024-09-13T20:04:05" version="4.3.0-dev-bf6b697-dirty">
     <name>Verovio</name>
     <p>Transcoded from Humdrum</p>
    </application>
   </appInfo>
  </encodingDesc>
  <extMeta>
   <frames xmlns="http://www.humdrum.org/ns/humxml" />
  </extMeta>
 </meiHead>
 <music decls="#work1_encoded">
  <body>
   <mdiv xml:id="mxs208g">
    <score xml:id="sou5b9o">
     <scoreDef xml:id="soehay" midi.bpm="60.000000" tempo.dist="3.0000vu">
      <staffGrp xml:id="s5ipkl">
       <staffDef xml:id="staffdef-L1F1" n="1" lines="5">
        <clef xml:id="c1w258xp" shape="G" line="2" />
        <meterSig xml:id="metersig-L2F1" count="4" unit="4" />
       </staffDef>
      </staffGrp>
     </scoreDef>
     <section xml:id="section-L1F1">
      <measure xml:id="measure-L1">
       <staff xml:id="staff-L1F1" n="1">
        <layer xml:id="layer-L1F1N1" n="1">
         <note xml:id="note-L4F1" dur="8" oct="4" pname="c" grace="unacc" accid.ges="n" />
         <note xml:id="note-L5F1" dur="2" oct="4" pname="d" accid.ges="n" />
         <note xml:id="note-L6F1" dur="8" oct="4" pname="e" grace="unacc" accid.ges="n" />
         <note xml:id="note-L7F1" dur="2" oct="4" pname="d" accid.ges="n" />
        </layer>
       </staff>
      </measure>
      <measure xml:id="measure-L8">
       <staff xml:id="staff-L8F1N1" n="1">
        <layer xml:id="layer-L8F1N1" n="1">
         <note xml:id="note-L9F1" dur="4" oct="4" pname="c" grace="acc" accid.ges="n" />
         <note xml:id="note-L10F1" dur="2" oct="4" pname="d" accid.ges="n" />
         <note xml:id="note-L11F1" dur="4" oct="4" pname="e" grace="acc" accid.ges="n" />
         <note xml:id="note-L12F1" dur="2" oct="4" pname="d" accid.ges="n" />
        </layer>
       </staff>
      </measure>
     </section>
    </score>
   </mdiv>
  </body>
 </music>
</mei>

First measure ones are @grace="unacc" (unaccented) which come before the following note, generally as fast as possible and there is no mechanism (I think) in MEI to control their duration). Second measure ones are @grace="acc" (accented), whihc are being implement currently as stealing 1/2 of the duration of the next note, which is then delayed by 1/2 of its original duration.

         <note xml:id="note-L4F1" dur="8" oct="4" pname="c" grace="unacc" accid.ges="n" />
         <note xml:id="note-L9F1" dur="4" oct="4" pname="c" grace="acc" accid.ges="n" />

@Dahurica
Copy link
Author

At present, this should be a normal grace note. I have isolated the problematic part of the XML instance. After consulting with a friend who studies music, they suggested that at 60 BPM, a single quarter grace note should last 0.25 seconds. For the first group of grace notes, the durations should be 0.03125 seconds, 0.03125 seconds, and 0.125 seconds respectively. They mentioned that the grace notes are generally too fast, making them hard to hear clearly, while the second group of grace notes is too slow.

Details
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 4.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="4.0">
  <work>
    <work-title>未命名乐谱</work-title>
    </work>
  <identification>
    <creator type="composer">作曲 / 编排</creator>
    <encoding>
      <software>MuseScore 4.3.0</software>
      <encoding-date>2024-09-14</encoding-date>
      <supports element="accidental" type="yes"/>
      <supports element="beam" type="yes"/>
      <supports element="print" attribute="new-page" type="no"/>
      <supports element="print" attribute="new-system" type="no"/>
      <supports element="stem" type="yes"/>
      </encoding>
    </identification>
  <part-list>
    <score-part id="P1">
      <part-name>钢琴</part-name>
      <part-abbreviation>Pno.</part-abbreviation>
      <score-instrument id="P1-I1">
        <instrument-name>钢琴</instrument-name>
        <instrument-sound>keyboard.piano</instrument-sound>
        </score-instrument>
      <midi-device id="P1-I1" port="1"></midi-device>
      <midi-instrument id="P1-I1">
        <midi-channel>1</midi-channel>
        <midi-program>1</midi-program>
        <volume>78.7402</volume>
        <pan>0</pan>
        </midi-instrument>
      </score-part>
    </part-list>
  <part id="P1">
    <measure number="1">
      <attributes>
        <divisions>1</divisions>
        <key>
          <fifths>0</fifths>
          </key>
        <time>
          <beats>4</beats>
          <beat-type>4</beat-type>
          </time>
        <staves>2</staves>
        <clef number="1">
          <sign>G</sign>
          <line>2</line>
          </clef>
        <clef number="2">
          <sign>F</sign>
          <line>4</line>
          </clef>
        </attributes>
      <direction placement="above">
        <direction-type>
          <words font-weight="bold" font-size="12">Grave</words>
          </direction-type>
        <staff>1</staff>
        <sound tempo="35"/>
        </direction>
      <direction placement="below">
        <direction-type>
          <pedal type="resume" line="yes" sign="yes"/>
          </direction-type>
        <staff>1</staff>
        </direction>
      <note>
        <pitch>
          <step>D</step>
          <octave>5</octave>
          </pitch>
        <duration>1</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note>
        <pitch>
          <step>C</step>
          <octave>5</octave>
          </pitch>
        <duration>1</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note>
        <pitch>
          <step>C</step>
          <octave>5</octave>
          </pitch>
        <duration>1</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <note>
        <pitch>
          <step>C</step>
          <octave>5</octave>
          </pitch>
        <duration>1</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>up</stem>
        <staff>1</staff>
        </note>
      <direction placement="below">
        <direction-type>
          <pedal type="stop" line="yes" sign="no"/>
          </direction-type>
        <staff>1</staff>
        </direction>
      <backup>
        <duration>4</duration>
        </backup>
      <note>
        <grace/>
        <pitch>
          <step>C</step>
          <octave>5</octave>
          </pitch>
        <voice>2</voice>
        <type>32nd</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">begin</beam>
        <beam number="2">begin</beam>
        <beam number="3">forward hook</beam>
        </note>
      <note>
        <grace/>
        <pitch>
          <step>C</step>
          <octave>5</octave>
          </pitch>
        <voice>2</voice>
        <type>16th</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">continue</beam>
        <beam number="2">end</beam>
        </note>
      <note>
        <grace slash="yes"/>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <voice>2</voice>
        <type>eighth</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">end</beam>
        </note>
      <note>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <duration>1</duration>
        <voice>2</voice>
        <type>quarter</type>
        <stem>down</stem>
        <staff>1</staff>
        </note>
      <note>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <duration>1</duration>
        <voice>2</voice>
        <type>quarter</type>
        <stem>down</stem>
        <staff>1</staff>
        </note>
      <note>
        <grace/>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <voice>2</voice>
        <type>32nd</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">begin</beam>
        <beam number="2">begin</beam>
        <beam number="3">begin</beam>
        </note>
      <note>
        <grace/>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <voice>2</voice>
        <type>32nd</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">end</beam>
        <beam number="2">end</beam>
        <beam number="3">end</beam>
        </note>
      <note>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <duration>1</duration>
        <voice>2</voice>
        <type>quarter</type>
        <stem>down</stem>
        <staff>1</staff>
        </note>
      <note>
        <grace/>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <voice>2</voice>
        <type>eighth</type>
        <stem>down</stem>
        <staff>1</staff>
        </note>
      <note>
        <pitch>
          <step>F</step>
          <octave>4</octave>
          </pitch>
        <duration>1</duration>
        <voice>2</voice>
        <type>quarter</type>
        <stem>down</stem>
        <staff>1</staff>
        </note>
      <backup>
        <duration>4</duration>
        </backup>
      <note>
        <rest measure="yes"/>
        <duration>4</duration>
        <voice>5</voice>
        <staff>2</staff>
        </note>
      <barline location="right">
        <bar-style>light-light</bar-style>
        </barline>
      </measure>
    <measure number="2">
      <direction placement="above">
        <direction-type>
          <words font-weight="bold" font-size="12">Largo</words>
          </direction-type>
        <staff>1</staff>
        <sound tempo="50"/>
        </direction>
      <direction placement="below">
        <direction-type>
          <dynamics>
            <p/>
            </dynamics>
          </direction-type>
        <staff>1</staff>
        <sound dynamics="54.44"/>
        </direction>
      <direction placement="below">
        <direction-type>
          <pedal type="resume" line="yes" sign="yes"/>
          </direction-type>
        <staff>1</staff>
        </direction>
      <note>
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>2</duration>
        <voice>1</voice>
        <type>whole</type>
        <time-modification>
          <actual-notes>2</actual-notes>
          <normal-notes>1</normal-notes>
          </time-modification>
        <staff>1</staff>
        <notations>
          <ornaments>
            <tremolo type="start">3</tremolo>
            </ornaments>
          </notations>
        </note>
      <note>
        <pitch>
          <step>A</step>
          <octave>4</octave>
          </pitch>
        <duration>2</duration>
        <voice>1</voice>
        <type>whole</type>
        <time-modification>
          <actual-notes>2</actual-notes>
          <normal-notes>1</normal-notes>
          </time-modification>
        <staff>1</staff>
        <notations>
          <ornaments>
            <tremolo type="stop">3</tremolo>
            </ornaments>
          </notations>
        </note>
      <direction placement="below">
        <direction-type>
          <pedal type="stop" line="yes" sign="no"/>
          </direction-type>
        <staff>1</staff>
        </direction>
      <backup>
        <duration>4</duration>
        </backup>
      <note>
        <pitch>
          <step>E</step>
          <octave>3</octave>
          </pitch>
        <duration>2</duration>
        <voice>5</voice>
        <type>whole</type>
        <time-modification>
          <actual-notes>2</actual-notes>
          <normal-notes>1</normal-notes>
          </time-modification>
        <staff>2</staff>
        <notations>
          <ornaments>
            <tremolo type="start">1</tremolo>
            </ornaments>
          </notations>
        </note>
      <note>
        <pitch>
          <step>C</step>
          <octave>3</octave>
          </pitch>
        <duration>2</duration>
        <voice>5</voice>
        <type>whole</type>
        <time-modification>
          <actual-notes>2</actual-notes>
          <normal-notes>1</normal-notes>
          </time-modification>
        <staff>2</staff>
        <notations>
          <ornaments>
            <tremolo type="stop">1</tremolo>
            </ornaments>
          </notations>
        </note>
      <barline location="right">
        <bar-style>light-heavy</bar-style>
        </barline>
      </measure>
    </part>
  </score-partwise>

PixPin_2024-09-14_11-10-01

@craigsapp
Copy link
Contributor

craigsapp commented Sep 14, 2024

Loading the MusicXML back into Musescore:

Screenshot 2024-09-14 at 12 09 26 AM

Analysis of the example MusicXML exported as MIDI from Musescore:

"MThd"			; MIDI header chunk marker
4'6			; bytes to follow in header chunk
2'1			; file format: Type-1 (multitrack)
2'2			; number of tracks
2'480			; ticks per quarter note

;;; TRACK 0 ----------------------------------
"MTrk"			; MIDI track chunk marker
4'364			; bytes to follow in track chunk
v0	ff 3 v6 "钢琴"	; track name
v0	ff 58 v4 '4 '2 '24 '8	; time signature
v0	ff 59 v2 '0 '0	; key signature
v0	ff 51 v3 t35	; tempo
v0	b0 '121 '0	; controller
v0	    '100 '0	; controller
v0	    '101 '0	; controller
v0	    '6 '12	; controller
v0	    '100 '127	; controller
v0	    '101 '127	; controller
v0	c0 '0	; patch-change
v0	b0 '7 '100	; controller
v0	    '10 '63	; controller
v0	    '91 '0	; controller
v0	    '93 '0	; controller
v0	ff 21 v1 '0	; MIDI port
v0	90 '74 '80	; note-on D5
v0	    '72 '80	; note-on C5
v0	    '72 '0	; note-off C5
v0	    '72 '80	; note-on C5
v0	    '72 '0	; note-off C5
v2	b0 '64 '127	; controller
v0	    '64 '0	; controller
v58	90 '64 '80	; note-on E4
v180	    '64 '0	; note-off E4
v0	    '64 '80	; note-on E4
v215	    '74 '0	; note-off D5
v24	    '64 '0	; note-off E4
v1	    '72 '80	; note-on C5
v0	    '64 '80	; note-on E4
v455	    '72 '0	; note-off C5
v0	    '64 '0	; note-off E4
v25	    '72 '80	; note-on C5
v60	    '64 '80	; note-on E4
v395	    '72 '0	; note-off C5
v2	    '64 '0	; note-off E4
v23	    '72 '80	; note-on C5
v240	    '65 '80	; note-on F4
v215	    '72 '0	; note-off C5
v12	    '65 '0	; note-off F4
v13	ff 51 v3 t50	; tempo
v0	90 '60 '49	; note-on C4
v2	b0 '64 '127	; controller
v0	    '64 '0	; controller
v52	90 '60 '0	; note-off C4
v5	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v6	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v5	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v6	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v5	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v6	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v5	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v6	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v5	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v6	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v5	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v6	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v5	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v6	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v5	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v6	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v5	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v6	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v5	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v6	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v5	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v6	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v5	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v6	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v6	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v5	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v6	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v5	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v6	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v5	    '60 '49	; note-on C4
v54	    '60 '0	; note-off C4
v6	    '69 '49	; note-on A4
v54	    '69 '0	; note-off A4
v1	ff 2f v0	; end-of-track

;;; TRACK 1 ----------------------------------
"MTrk"			; MIDI track chunk marker
4'83			; bytes to follow in track chunk
v0	ff 3 v6 "钢琴"	; track name
v0	ff 59 v2 '0 '0	; key signature
v0	ff 21 v1 '0	; MIDI port
v1920	90 '52 '49	; note-on E3
v226	    '52 '0	; note-off E3
v14	    '48 '49	; note-on C3
v226	    '48 '0	; note-off C3
v14	    '52 '49	; note-on E3
v226	    '52 '0	; note-off E3
v14	    '48 '49	; note-on C3
v226	    '48 '0	; note-off C3
v14	    '52 '49	; note-on E3
v226	    '52 '0	; note-off E3
v14	    '48 '49	; note-on C3
v226	    '48 '0	; note-off C3
v14	    '52 '49	; note-on E3
v226	    '52 '0	; note-off E3
v14	    '48 '49	; note-on C3
v226	    '48 '0	; note-off C3
v1	ff 2f v0	; end-of-track

This is not a completely standard MIDI file: For multi-track MIDI files, track 0 should be an "expression track" with no notes, only things like tempo changes should be in that track.

Here are the list of notes in the file:

Track Q Qdur Qioi Tick Tdur Sec Sdur Note
0 0 0.948 0 0 455 0 1.625 D5
0 0 0 0 0 0 0 0 C5
0 0 0 60 0 0 0 0 C5
0 0.125 0.375 180 60 180 0.214 0.643 E4
0 0.5 0.498 240 240 239 0.857 0.854 E4
0 1 0.948 0 480 455 1.714 1.625 C5
0 1 0.948 480 480 455 1.714 1.625 E4
0 2 0.948 60 960 455 3.429 1.625 C5
0 2.125 0.827 420 1020 397 3.643 1.418 E4
0 3 0.948 240 1440 455 5.143 1.625 C5
0 3.5 0.473 240 1680 227 6 0.811 F4
0 4 0.113 0 1920 54 6.857 0.135 C4
1 4 0.471 59 1920 226 6.857 0.565 E3
0 4.123 0.113 60 1979 54 7.005 0.135 A4
0 4.248 0.113 59 2039 54 7.155 0.135 C4
0 4.371 0.113 60 2098 54 7.302 0.135 A4
0 4.496 0.113 2 2158 54 7.452 0.135 C4
1 4.5 0.471 57 2160 226 7.457 0.565 C3
0 4.619 0.113 60 2217 54 7.6 0.135 A4
0 4.744 0.113 59 2277 54 7.75 0.135 C4
0 4.867 0.113 60 2336 54 7.897 0.135 A4
0 4.992 0.113 4 2396 54 8.047 0.135 C4
1 5 0.471 55 2400 226 8.057 0.565 E3
0 5.115 0.113 60 2455 54 8.195 0.135 A4
0 5.24 0.113 59 2515 54 8.345 0.135 C4
0 5.363 0.113 60 2574 54 8.492 0.135 A4
0 5.488 0.113 6 2634 54 8.642 0.135 C4
1 5.5 0.471 53 2640 226 8.657 0.565 C3
0 5.61 0.113 60 2693 54 8.79 0.135 A4
0 5.735 0.113 59 2753 54 8.94 0.135 C4
0 5.858 0.113 60 2812 54 9.087 0.135 A4
0 5.983 0.113 8 2872 54 9.237 0.135 C4
1 6 0.471 51 2880 226 9.257 0.565 E3
0 6.106 0.113 60 2931 54 9.385 0.135 A4
0 6.231 0.113 59 2991 54 9.535 0.135 C4
0 6.354 0.113 60 3050 54 9.682 0.135 A4
0 6.479 0.113 10 3110 54 9.832 0.135 C4
1 6.5 0.471 49 3120 226 9.857 0.565 C3
0 6.602 0.113 60 3169 54 9.98 0.135 A4
0 6.727 0.113 59 3229 54 10.13 0.135 C4
0 6.85 0.113 60 3288 54 10.277 0.135 A4
0 6.975 0.113 12 3348 54 10.427 0.135 C4
1 7 0.471 48 3360 226 10.457 0.565 E3
0 7.1 0.113 59 3408 54 10.577 0.135 A4
0 7.223 0.113 60 3467 54 10.725 0.135 C4
0 7.348 0.113 59 3527 54 10.875 0.135 A4
0 7.471 0.113 14 3586 54 11.022 0.135 C4
1 7.5 0.471 46 3600 226 11.057 0.565 C3
0 7.596 0.113 59 3646 54 11.172 0.135 A4
0 7.719 0.113 60 3705 54 11.32 0.135 C4
0 7.844 0.113 none 3765 54 11.47 0.135 A4

The first two C5 grace notes have durations of 0, which is strange.

Visualization of the notes (when durations are not 0):

Screenshot 2024-09-14 at 12 04 56 AM

Other than the two zero-length C5 grace notes, Musescore is not exporting any of the other grace notes. It is playing them in Musescore, however. The second and third group of grace notes are performed as @grace="acc" in Musescore.


Analysis of the MIDI output from verovio:

"MThd"			; MIDI header chunk marker
4'6			; bytes to follow in header chunk
2'1			; file format: Type-1 (multitrack)
2'3			; number of tracks
2'120			; ticks per quarter note

;;; TRACK 0 ----------------------------------
"MTrk"			; MIDI track chunk marker
4'54			; bytes to follow in track chunk
v0	ff 51 v3 t120	; tempo
v0	ff 51 v3 t35	; tempo
v0	ff 51 v3 t35	; tempo
v0	ff 51 v3 t35	; tempo
v480	ff 51 v3 t50	; tempo
v0	ff 51 v3 t50	; tempo
v0	ff 51 v3 t50	; tempo
v0	ff 2f v0	; end-of-track

;;; TRACK 1 ----------------------------------
"MTrk"			; MIDI track chunk marker
4'177			; bytes to follow in track chunk
v0	ff 3 v6 "钢琴"	; track name
v0	ff 59 v2 '0 '0	; key signature
v0	ff 58 v4 '4 '2 '24 '8	; time signature
v0	c0 '0	; patch-change
v0	90 '74 '90	; note-on D5
v0	90 '72 '90	; note-on C5
v1	90 '72 '0	; note-off C5
v0	90 '72 '90	; note-on C5
v2	90 '72 '0	; note-off C5
v0	90 '64 '90	; note-on E4
v2	90 '64 '0	; note-off E4
v0	90 '64 '90	; note-on E4
v115	90 '64 '0	; note-off E4
v0	90 '74 '0	; note-off D5
v0	90 '72 '90	; note-on C5
v0	90 '64 '90	; note-on E4
v120	90 '72 '0	; note-off C5
v0	90 '64 '0	; note-off E4
v0	90 '72 '90	; note-on C5
v0	90 '64 '90	; note-on E4
v30	90 '64 '0	; note-off E4
v0	90 '64 '90	; note-on E4
v30	90 '64 '0	; note-off E4
v0	90 '64 '90	; note-on E4
v60	90 '64 '0	; note-off E4
v0	90 '72 '0	; note-off C5
v0	90 '64 '90	; note-on E4
v0	90 '72 '90	; note-on C5
v60	90 '64 '0	; note-off E4
v0	90 '65 '90	; note-on F4
v48	b0 '64 '0	; controller
v0	b0 '64 '0	; controller
v12	90 '65 '0	; note-off F4
v0	90 '72 '0	; note-off C5
v0	90 '60 '90	; note-on C4
v240	90 '60 '0	; note-off C4
v0	90 '69 '90	; note-on A4
v228	b0 '64 '0	; controller
v0	b0 '64 '0	; controller
v12	90 '69 '0	; note-off A4
v0	ff 2f v0	; end-of-track

;;; TRACK 2 ----------------------------------
"MTrk"			; MIDI track chunk marker
4'58			; bytes to follow in track chunk
v0	ff 3 v6 "钢琴"	; track name
v0	ff 59 v2 '0 '0	; key signature
v0	ff 58 v4 '4 '2 '24 '8	; time signature
v0	c0 '0	; patch-change
v468	b0 '64 '0	; controller
v12	90 '52 '90	; note-on E3
v240	90 '52 '0	; note-off E3
v0	90 '48 '90	; note-on C3
v228	b0 '64 '0	; controller
v12	90 '48 '0	; note-off C3
v0	ff 2f v0	; end-of-track

Verovio is correctly creating a Type-1 MIDI file, with three tracks, the first one with only tempos as expected (and unlike Musescore v4.4 MIDI output).

However, there are too many tempo changes in track 0:

;;; TRACK 0 ----------------------------------
"MTrk"			; MIDI track chunk marker
4'54			; bytes to follow in track chunk
v0	ff 51 v3 t120	; tempo
v0	ff 51 v3 t35	; tempo
v0	ff 51 v3 t35	; tempo
v0	ff 51 v3 t35	; tempo
v480	ff 51 v3 t50	; tempo
v0	ff 51 v3 t50	; tempo
v0	ff 51 v3 t50	; tempo
v0	ff 2f v0	; end-of-track

There should only be two: one for q=35, and another q=50. There is a spurious q=120 at the start, and then the two tempo changes are tripled for some reason (probably related to there being three tracks in the MIDI file).

MIDI notes in the verovio midifile:

Track Q Qdur Qioi Tick Tdur Sec Sdur Note
1 0 1 0 0 120 0 1.714 D5
1 0 0.008 1 0 1 0 0.014 C5
1 0.008 0.017 2 1 2 0.014 0.029 C5
1 0.025 0.017 2 3 2 0.043 0.029 E4
1 0.042 0.958 115 5 115 0.071 1.643 E4
1 1 1 0 120 120 1.714 1.714 C5
1 1 1 120 120 120 1.714 1.714 E4
1 2 1 0 240 120 3.429 1.714 C5
1 2 0.25 30 240 30 3.429 0.429 E4
1 2.25 0.25 30 270 30 3.857 0.429 E4
1 2.5 0.5 60 300 60 4.286 0.857 E4
1 3 0.5 0 360 60 5.143 0.857 E4
1 3 1 60 360 120 5.143 1.714 C5
1 3.5 0.5 60 420 60 6 0.857 F4
1 4 2 0 480 240 6.857 2.4 C4
2 4 2 240 480 240 6.857 2.4 E3
1 6 2 0 720 240 9.257 2.4 A4
2 6 2 none 720 240 9.257 2.4 C3

The first three grace notes have tick durations of (1, 2, 2), or in milliseconds (17, 29, 29). The first one at 17 ms might be due to being at the very start of the MIDI data or related to rounding error of some type. The 29 ms ones are as expected since 27 ms probably cannot be represented due to tick quantization. The grace notes are being played the same time as the D6 note (which is may be related to being at the start of the MIDI; otherwise if they are @grace="acc", then they should be coming before the regular E4 note, which is delayed by 5 ticks). The other grace notes are treated as @grace="acc". Stealing two sixteenths for the double grace notes and stealing an eighth note from the last grace note.

Visualization:

Screenshot 2024-09-14 at 12 22 19 AM

Here is the intermediate MEI data:

Click to view MEI conversion of test example.
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0">
 <meiHead xml:id="mvi1hiz">
  <fileDesc xml:id="f1mwjstj">
   <titleStmt xml:id="t197sbu5">
    <title>未命名乐谱</title>
    <respStmt>
     <persName role="composer">作曲 / 编排</persName>
    </respStmt>
   </titleStmt>
   <pubStmt xml:id="p1iw7c8o">
    <date isodate="2024-09-14" type="encoding-date">2024-09-14</date>
   </pubStmt>
  </fileDesc>
  <encodingDesc xml:id="e1iqvtql">
   <appInfo xml:id="atak9nq">
    <application xml:id="a1j4kf1f" isodate="2024-09-14T00:30:39" version="4.3.0-dev-7cf6fff">
     <name xml:id="n631uec">Verovio</name>
     <p xml:id="p114sm3o">Transcoded from MusicXML</p>
    </application>
   </appInfo>
  </encodingDesc>
 </meiHead>
 <music>
  <body>
   <mdiv xml:id="m18m8ymp">
    <score xml:id="sf8thph">
     <scoreDef xml:id="s13am7v1">
      <staffGrp xml:id="s1es7uuz">
       <staffGrp xml:id="P1" bar.thru="true">
        <grpSym xml:id="g1a0k4qm" symbol="brace" />
        <label xml:id="l1eem0yc">钢琴</label>
        <labelAbbr xml:id="l7xgdh6">Pno.</labelAbbr>
        <instrDef xml:id="i1qda519" midi.channel="0" midi.instrnum="0" midi.volume="78.00%" />
        <staffDef xml:id="s17c6e3l" n="1" lines="5" ppq="1">
         <clef xml:id="c1snn1fs" shape="G" line="2" />
         <keySig xml:id="k17ra35o" sig="0" />
         <meterSig xml:id="m13t1sku" count="4" unit="4" />
        </staffDef>
        <staffDef xml:id="s1rvhz37" n="2" lines="5" ppq="1">
         <clef xml:id="c1irr73i" shape="F" line="4" />
         <keySig xml:id="k3qkxcv" sig="0" />
         <meterSig xml:id="m11jjdw7" count="4" unit="4" />
        </staffDef>
       </staffGrp>
      </staffGrp>
     </scoreDef>
     <section xml:id="shlfnt">
      <measure xml:id="m364bvm" right="dbl" n="1">
       <staff xml:id="s930dg4" n="1">
        <layer xml:id="l126vrmn" n="1">
         <note xml:id="n1txx78l" dur.ppq="1" dur="4" oct="5" pname="d" stem.dir="up" />
         <note xml:id="ncuagvx" dur.ppq="1" dur="4" oct="5" pname="c" stem.dir="up" />
         <note xml:id="na7d7nu" dur.ppq="1" dur="4" oct="5" pname="c" stem.dir="up" />
         <note xml:id="nahvn12" dur.ppq="1" dur="4" oct="5" pname="c" stem.dir="up" />
        </layer>
        <layer xml:id="l1ntjeud" n="2">
         <beam xml:id="bmq3g6k">
          <note xml:id="n1tulqz3" dur.ppq="0" dur="32" oct="5" pname="c" grace="acc" stem.dir="down" />
          <note xml:id="nfb9vln" breaksec="1" dur.ppq="0" dur="16" oct="5" pname="c" grace="acc" stem.dir="down" />
          <note xml:id="n1cy7jcd" dur.ppq="0" dur="8" oct="4" pname="e" grace="unacc" stem.dir="down" stem.mod="1slash" />
         </beam>
         <note xml:id="nvwpvsk" dur.ppq="1" dur="4" oct="4" pname="e" stem.dir="down" />
         <note xml:id="nr0mlr0" dur.ppq="1" dur="4" oct="4" pname="e" stem.dir="down" />
         <beam xml:id="b1re77sm">
          <note xml:id="n14o2h9k" dur.ppq="0" dur="32" oct="4" pname="e" grace="acc" stem.dir="down" />
          <note xml:id="n1ly7zvq" dur.ppq="0" dur="32" oct="4" pname="e" grace="acc" stem.dir="down" />
         </beam>
         <note xml:id="n1h71bwd" dur.ppq="1" dur="4" oct="4" pname="e" stem.dir="down" />
         <note xml:id="nd5i5t1" dur.ppq="0" dur="8" oct="4" pname="e" grace="acc" stem.dir="down" />
         <note xml:id="nwq71cw" dur.ppq="1" dur="4" oct="4" pname="f" stem.dir="down" />
        </layer>
       </staff>
       <staff xml:id="ssplueg" n="2">
        <layer xml:id="lspgc3l" n="5">
         <mRest xml:id="mrxz6d6" />
        </layer>
       </staff>
       <tempo xml:id="tv9d1gw" place="above" staff="1" tstamp="1.000000" xml:lang="it" midi.bpm="35.000000">
        <rend xml:id="rtm0dsh" fontweight="bold">Grave</rend>
       </tempo>
       <pedal xml:id="p10w1lbj" staff="1" tstamp="1.000000" form="line" place="below" vgrp="2000" />
       <pedal xml:id="pqc5nl4" staff="1" tstamp="4.900000" dir="up" form="line" place="below" vgrp="2000" />
      </measure>
      <measure xml:id="malp1k5" right="end" n="2">
       <staff xml:id="s2i5wcu" n="1">
        <layer xml:id="ljd9vjj" n="1">
         <fTrem xml:id="fzz77tw" beams="3" beams.float="3">
          <note xml:id="n1bdn2cp" dur.ppq="2" dur="1" oct="4" pname="c" />
          <note xml:id="n1trqoo5" dur.ppq="2" dur="1" oct="4" pname="a" />
         </fTrem>
        </layer>
       </staff>
       <staff xml:id="s1np4g2g" n="2">
        <layer xml:id="l1xf8shg" n="5">
         <fTrem xml:id="fh5smfy" beams="1" beams.float="1">
          <note xml:id="n1mki2n2" dur.ppq="2" dur="1" oct="3" pname="e" />
          <note xml:id="n9z38h9" dur.ppq="2" dur="1" oct="3" pname="c" />
         </fTrem>
        </layer>
       </staff>
       <tempo xml:id="tk0gpuf" place="above" staff="1" tstamp="1.000000" xml:lang="it" midi.bpm="50.000000">
        <rend xml:id="r97602f" fontweight="bold">Largo</rend>
       </tempo>
       <dynam xml:id="d6ul3d2" place="below" staff="1" tstamp="1.000000" val="49" vgrp="2000">p</dynam>
       <pedal xml:id="pyolx4x" staff="1" tstamp="1.000000" form="line" place="below" vgrp="2000" />
       <pedal xml:id="pq9hk11" staff="1" tstamp="4.900000" dir="up" form="line" place="below" vgrp="2000" />
      </measure>
     </section>
    </score>
   </mdiv>
  </body>
 </music>
</mei>

All grace notes except the third one are @grace="acc", with the third one being @grace="unacc"`

The third one in MusicXML:

      <note>
        <grace slash="yes"/>
        <pitch>
          <step>E</step>
          <octave>4</octave>
          </pitch>
        <voice>2</voice>
        <type>eighth</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">end</beam>
        </note>
      <note>

With the <grace slash="yes"/> being converted to @grace="unacc" (as expected).

The others are <grace/> being converted to @grace="unacc" (as expected).

Behavior of the last three grace notes are expected according to how these are treated in verovio currently. (first two are not, but this might be related to the third grace note being @grace="unacc", and the acc and unacc types cannot really be mixed, particularly when the unacc one follow an acc one).

Preferrably `@grace="acc" should not steal 1/2 of the duration of the following note, but rather steal the duration according to the visual duration of those grace notes.

The playback of the 4th and 5th grace notes is related to verovio rendering converting them to 16th notes rather than as 32nd notes.

I do hear the first D5 note in Verovio MIDI output and playback with WildWebMidi (WildWebMidi has a problem with overlapping notes on the same pitch, but that problem does not occur in this example). In Musescore playback, I do not hear starting D6 note (but that note is exported in the MIDI output from Musescore).

The timemap positions of the grace notes seems to be incorrect. Playing this example in VHV has all of the grace notes for the measure highlighting on beat one. The playback is correct but the highlighting is wrong (possibly related to VHV, but more likely in the timemap). There was a problem in the past with the grace notes playing improperly at the start of a measure when they were in secondary(?) layers, but this was fixed, and possibly the same fix is needed for the timemap).

@craigsapp
Copy link
Contributor

Related to the duplication of the tempo markings in the verovio MIDI output, this test MEI file does not have a problem:
Screenshot 2024-09-14 at 12 50 57 AM

Click to view MEI data for above example
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0">
 <meiHead>
  <fileDesc>
   <titleStmt>
    <title />
   </titleStmt>
   <pubStmt>
   </pubStmt>
  </fileDesc>
  <encodingDesc>
   <appInfo>
    <application isodate="2024-09-14T00:48:52" version="4.3.0-dev-bf6b697-dirty">
     <name>Verovio</name>
     <p>Transcoded from Humdrum</p>
    </application>
   </appInfo>
  </encodingDesc>
  <extMeta>
   <frames xmlns="http://www.humdrum.org/ns/humxml" />
  </extMeta>
 </meiHead>
 <music decls="#work1_encoded">
  <body>
   <mdiv xml:id="m16x8r3f">
    <score xml:id="sdszddl">
     <scoreDef xml:id="ss3btj4" midi.bpm="80.000000" tempo.dist="3.0000vu">
      <staffGrp xml:id="s1eluelt" bar.thru="true" symbol="brace">
       <staffDef xml:id="staffdef-L1F2" n="1" lines="5">
        <clef xml:id="c47hkko" shape="G" line="2" />
        <meterSig xml:id="metersig-L2F2" count="4" unit="4" />
       </staffDef>
       <staffDef xml:id="staffdef-L1F1" n="2" lines="5">
        <clef xml:id="cwsinwy" shape="F" line="4" />
        <meterSig xml:id="metersig-L2F1" count="4" unit="4" />
       </staffDef>
      </staffGrp>
     </scoreDef>
     <section xml:id="section-L1F1">
      <measure xml:id="measure-L1">
       <staff xml:id="staff-L1F2" n="1">
        <layer xml:id="layer-L1F2N1" n="1">
         <note xml:id="note-L4F2" dur="1" oct="5" pname="c" accid.ges="n" />
        </layer>
       </staff>
       <staff xml:id="staff-L1F1" n="2">
        <layer xml:id="layer-L1F1N1" n="1">
         <note xml:id="note-L4F1" dur="1" oct="3" pname="c" accid.ges="n" />
        </layer>
       </staff>
      </measure>
     </section>
    </score>
   </mdiv>
  </body>
 </music>
</mei>

MIDI output from verovio:

"MThd"			; MIDI header chunk marker
4'6			; bytes to follow in header chunk
2'1			; file format: Type-1 (multitrack)
2'3			; number of tracks
2'120			; ticks per quarter note

;;; TRACK 0 ----------------------------------
"MTrk"			; MIDI track chunk marker
4'11			; bytes to follow in track chunk
v0	ff 51 v3 t80	; tempo
v0	ff 2f v0	; end-of-track

;;; TRACK 1 ----------------------------------
"MTrk"			; MIDI track chunk marker
4'21			; bytes to follow in track chunk
v0	ff 58 v4 '4 '2 '24 '8	; time signature
v0	90 '72 '90	; note-on C5
v480	90 '72 '0	; note-off C5
v0	ff 2f v0	; end-of-track

;;; TRACK 2 ----------------------------------
"MTrk"			; MIDI track chunk marker
4'21			; bytes to follow in track chunk
v0	ff 58 v4 '4 '2 '24 '8	; time signature
v0	90 '48 '90	; note-on C3
v480	90 '48 '0	; note-off C3
v0	ff 2f v0	; end-of-track

Only one tempo change (q=80) is present in the MIDI output from verovio for this short example.

@Dahurica
Copy link
Author

Sure, thank you very much for your response. We found that both MuseScore and Sibelius confirm what you said. Just a quick question: are effects like multi-note tremolos and trills in your plans?

@craigsapp
Copy link
Contributor

craigsapp commented Sep 14, 2024

The problem with the two unaccented 32nd grace notes (grace notes 4 & 5 that you label as "too slow") are related to this discussion: #2579.

@craigsapp
Copy link
Contributor

There is also a problem that will need to be address at some point related to unaccented grace notes at the start of the music. Such grace notes cannot be place in negative time, so some extra time padding needs to be added to insert unaccented grace notes before regular notes at tick-time 0. Adding any padding to the MIDI data will require coordination with the timemap to make sure the extra time padding to the start of the music is included in the timemap timings. For example if an unaccented grace note needs to be inserted at time -27 ms, then the first regular notes should start at time 27 ms (and all other notes after time 0 should have 27 ms added to them to account for this padding).

This example has a strange example mixing accented and unaccented grace notes, which should be considered a data error. But if the first two were marked as unaccented (by adding a slash in the MusicXML data for them), then there should be time padding added for these three three grace notes at the start of the music.

It may be useful to add an option to verovio to set the duration of unaccented grace notes so that durations other than 27 ms could be rendered in the MIDI output. Ideally MEI would add a prarameter (if it is not already there) for grace notes to specify the duration of grace notes. This would be useful for both accented and unaccented grace notes, and it is not unreasonable to have different durations for unaccented grace notes within one work (particularly if there are grace notes in both slow and fast tempos).

For unaccented grace notes, it would be much preferred to use a modern interpretation, where the time stolen from the following note is equal to the visual duration(s) of the accented grace notes. Using an attribute on the grace notes that gives their durations in seconds (or milliseconds) can be used to control the rendering of the durations of the grace notes in the MIDI output (and indirectly the duration of the following note, which would be the duration of that note minus the duration(s) of the appoggiatura notes before it. In other words, the current system seems to be taking 1/2 of the following notes duration and splitting it between the two accented grace notes in this example, making the two grace notes render as sixteenth notes. Instead it should be noted that the two unaccented grace notes are visually 32nd notes, so only a sixteenth note duration should be taken from the following note. If another duration should be used for these notes, then ideally @dur.ges should be used to indicate that they should be rendred as 16th notes rather than 32nd notes (but it cannot since verovio uses that for alignment between layers and staves).

@craigsapp
Copy link
Contributor

multi-note tremolos and trills in your plans?

Yes, but note that the original request was from 2021 (and I think there may have been one in 2016), so you can project from those date on when other ornamentations may be added 😉 Making lots of assumptions, the Secretary Problem can be used to predict that it should be implemented within the next five years. (3 years is 37% of 8 years, so 5 more years (8 - 3).

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

No branches or pull requests

2 participants