Open Dahurica opened 2 months ago
A request for mordents, trills, turn, etc for MIDI export has an issue already: https://github.com/rism-digital/verovio/issues/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: https://github.com/rism-digital/verovio/issues/3754 https://github.com/rism-digital/verovio/issues/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
Note that there are two types of grace notes in MEI: accacciaturas rendered with slashes and appoggiaturas redered without slashes:
Transcoded from Humdrum
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" />
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.
Loading the MusicXML back into Musescore:
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):
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:
Here is the intermediate MEI data:
Transcoded from MusicXML
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).
Related to the duplication of the tempo markings in the verovio MIDI output, this test MEI file does not have a problem:
Transcoded from Humdrum
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.
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?
The problem with the two unaccented 32nd grace notes (grace notes 4 & 5 that you label as "too slow") are related to this discussion: https://github.com/rism-digital/verovio/issues/2579.
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).
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
).
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:
```javascriptIn 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