Open craigsapp opened 8 years ago
Repeats should not be too difficult. Endings will indeed be more complicated but OK, and Da Capo and so on even more. For these I think there is a need for discussion in MEI.
Technically this features has now been implemented, since verovio can now expand a score and output a MIDI file (using the --expand
option).
But a second stage of implementation would be to render an expanded MIDI file while keeping the score in compressed format. This would allow live playback of the MIDI data with WildWebMidi with the same score in compressed mode, where the note highlighting would jump around in the score according to the repeats (currently the score can be expanded and the MIDI file is a straight pass through the expanded score).
Here is a test case:
This score would be displayed, but the MIDI file would play the sequence C D C E F F, and the notes would highlight in that sequence. (also there could be another expansion for only second endings, which would produce C E F in the MIDI).
The output timemap for the compressed score is currently (this should probably remain the default if no MIDI expansion is requested):
[
{
"tstamp": 0.000000,
"qstamp": 0.000000,
"tempo": 60,
"on": ["note-L7F1"]
},
{
"tstamp": 4000.000000,
"qstamp": 4.000000,
"on": ["note-L10F1"],
"off": ["note-L7F1"]
},
{
"tstamp": 8000.000000,
"qstamp": 8.000000,
"on": ["note-L13F1"],
"off": ["note-L10F1"]
},
{
"tstamp": 12000.000000,
"qstamp": 12.000000,
"on": ["note-L16F1"],
"off": ["note-L13F1"]
},
{
"tstamp": 16000.000000,
"qstamp": 16.000000,
"off": ["note-L16F1"]
}
]
Here is what the timemap (and matching MIDI file) should be produced if an expanded MIDI file is requested:
[
{
"tstamp": 0.000000, // C (note-L7F1)
"qstamp": 0.000000,
"tempo": 60,
"on": ["note-L7F1"]
},
{
"tstamp": 4000.000000, // D (note-L10F1)
"qstamp": 4.000000,
"on": ["note-L10F1"],
"off": ["note-L7F1"]
},
{
"tstamp": 8000.000000, // C (note-L7F1)
"qstamp": 0.000000,
"tempo": 60,
"on": ["note-L7F1"],
"off": ["note-L10F1"]
},
{
"tstamp": 12000.000000, // E (note-L13F1)
"qstamp": 8.000000,
"on": ["note-L13F1"],
"off": ["note-L7F1"]
},
{
"tstamp": 16000.000000, // F (note-L16F1)
"qstamp": 12.000000,
"on": ["note-L16F1"],
"off": ["note-L13F1"]
},
{
"tstamp": 20000.000000, // F (note-L16F1)
"qstamp": 12.000000,
"on": ["note-L16F1"],
"off": ["note-L16F1"]
},
{
"tstamp": 24000.000000, // end
"qstamp": 16.000000,
"off": ["note-L16F1"]
}
]
The tstamp
variable always increased in the timemap (millisecond time in the MIDI file), but the qstamp
will decrease whenever there is a repeat happening.
Here is the distilled timemap:
real score
0 0
4000 4
8000 0
12000 8
16000 12
20000 12
24000 16
In the MEI score, the time data would be reversed, with potentially multiple realTime values stored for each note:
score real
0 [0, 8000]
4 [4000]
8 [12000]
12 [16000, 20000]
So for example, the first note would have two realTime values: 0 for the first repeat, and 8000 for the second repeat. Likewise, the note in the last measure at scoreTime 12 would have an array containing the two realTime values 16000 and 20000.
If there were an expansion list for the second endings only, then the score's note would have the values related to the timings of the notes in the shortened MIDI file:
score real
0 [0]
4 []
8 [4000]
12 [8000]
Notice that the realTime values for the first ending note (D) is never played, so it has an empty realTime.
Test MEI data:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.0">
<meiHead>
<fileDesc>
<titleStmt>
<title />
</titleStmt>
<pubStmt />
</fileDesc>
<encodingDesc>
<appInfo>
<application isodate="2021-02-02T23:23:59" version="3.2.0-dev-8f1ece3-dirty">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workList>
<work>
<title />
</work>
</workList>
</meiHead>
<music>
<body>
<mdiv xml:id="mdiv-0000001923652048">
<score xml:id="score-0000001831078766">
<scoreDef xml:id="scoredef-0000001634015516" midi.bpm="60">
<staffGrp xml:id="staffgrp-0000001108141941">
<staffDef xml:id="staffdef-0000000076573858" n="1" lines="5">
<clef xml:id="clef-L2F1" shape="G" line="2" />
<meterSig xml:id="metersig-L3F1" count="4" unit="4" />
</staffDef>
</staffGrp>
</scoreDef>
<section xml:id="section-L1F1">
<expansion plist="#label-A #label-A1 #label-A #label-A2 #label-B #label-B" xml:id="expansion-L4F1" />
<section xml:id="label-A">
<measure xml:id="measure-L1" n="1">
<staff xml:id="staff-0000000685011685" n="1">
<layer xml:id="layer-L1F1N1" n="1">
<note xml:id="note-L7F1" dur="1" oct="4" pname="c" accid.ges="n" />
</layer>
</staff>
</measure>
</section>
<ending xml:id="label-A1" n="1">
<measure xml:id="measure-L8" right="rptend" n="2">
<staff xml:id="staff-L8F1N1" n="1">
<layer xml:id="layer-L8F1N1" n="1">
<note xml:id="note-L10F1" dur="1" oct="4" pname="d" accid.ges="n" />
</layer>
</staff>
</measure>
</ending>
<ending xml:id="label-A2" n="2">
<measure xml:id="measure-L11" n="3">
<staff xml:id="staff-L11F1N1" n="1">
<layer xml:id="layer-L11F1N1" n="1">
<note xml:id="note-L13F1" dur="1" oct="4" pname="e" accid.ges="n" />
</layer>
</staff>
</measure>
</ending>
<section xml:id="label-B">
<measure xml:id="measure-L14" left="rptstart" right="rptend" n="4">
<staff xml:id="staff-L14F1N1" n="1">
<layer xml:id="layer-L14F1N1" n="1">
<note xml:id="note-L16F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
</section>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
And a test containing a second-ending expansion:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.0">
<meiHead>
<fileDesc>
<titleStmt>
<title />
</titleStmt>
<pubStmt />
</fileDesc>
<encodingDesc>
<appInfo>
<application isodate="2021-02-02T23:23:19" version="3.2.0-dev-8f1ece3-dirty">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workList>
<work>
<title />
</work>
</workList>
</meiHead>
<music>
<body>
<mdiv xml:id="mdiv-0000000048699960">
<score xml:id="score-0000001258871766">
<scoreDef xml:id="scoredef-0000001634015516" midi.bpm="60">
<staffGrp xml:id="staffgrp-0000002139912416">
<staffDef xml:id="staffdef-0000000014370509" n="1" lines="5">
<clef xml:id="clef-L2F1" shape="G" line="2" />
<meterSig xml:id="metersig-L3F1" count="4" unit="4" />
</staffDef>
</staffGrp>
</scoreDef>
<section xml:id="section-L1F1">
<choice xml:id="choice-0000001179785592">
<orig xml:id="orig-0000001713763553">
<expansion plist="#label-A #label-A1 #label-A #label-A2 #label-B #label-B" xml:id="expansion-L4F1" />
</orig>
<reg xml:id="reg-0000000163708006" type="norep">
<expansion plist="#label-A #label-A2 #label-B" xml:id="expansion-L5F1" type="norep" />
</reg>
</choice>
<section xml:id="label-A">
<measure xml:id="measure-L1" n="1">
<staff xml:id="staff-0000000725373844" n="1">
<layer xml:id="layer-L1F1N1" n="1">
<note xml:id="note-L8F1" dur="1" oct="4" pname="c" accid.ges="n" />
</layer>
</staff>
</measure>
</section>
<ending xml:id="label-A1" n="1">
<measure xml:id="measure-L9" right="rptend" n="2">
<staff xml:id="staff-L9F1N1" n="1">
<layer xml:id="layer-L9F1N1" n="1">
<note xml:id="note-L11F1" dur="1" oct="4" pname="d" accid.ges="n" />
</layer>
</staff>
</measure>
</ending>
<ending xml:id="label-A2" n="2">
<measure xml:id="measure-L12" n="3">
<staff xml:id="staff-L12F1N1" n="1">
<layer xml:id="layer-L12F1N1" n="1">
<note xml:id="note-L14F1" dur="1" oct="4" pname="e" accid.ges="n" />
</layer>
</staff>
</measure>
</ending>
<section xml:id="label-B">
<measure xml:id="measure-L15" left="rptstart" right="rptend" n="4">
<staff xml:id="staff-L15F1N1" n="1">
<layer xml:id="layer-L15F1N1" n="1">
<note xml:id="note-L17F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
</section>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
I'm trying to use the expand option on the RenderToTimemap on the JS lib. However, it always returns the same result as using it without it.
timemap = tk.renderToTimemap({
expand: "expansion-L4F1"
});
However on the command line I can see the expect result while using the --expand
option.
There is something that I could be using wrong here?
You need to set the option before loading the data.
Like this?
console.log("Verovio has loaded!");
options = {
pageWidth: pageWidth,
scale: zoom,
expand: "expansion-L4F1",
// Add an option to pass note@pname and note@oct as svg @data-*
svgAdditionalAttribute: ["note@pname", "note@oct"]
};
tk.setOptions(options);
let svg = tk.renderData(meiXML, {
});
That code will generate the following error on my Browser:
I am getting the same error.
(I have posted this on the Slack Verovio channel earlier.)
I have a problem with getting expansions work in the toolkit. In this example, the toolkit crashes when having to expand “expansion-repeat” or “expansion-default”. It works correctly when expansion set to “expansion-minimal”.
It seems when the toolkit has to add elements it crashes, when it removes elements, it works. (All these functions work correctly from the command line.)
Ah, I just see that it was raised again in #3314 and fixed through a90b43bb54b62331c2018dbe3699617c0fd62581.
Technically this features has now been implemented, since verovio can now expand a score and output a MIDI file (using the
--expand
option).But a second stage of implementation would be to render an expanded MIDI file while keeping the score in compressed format. This would allow live playback of the MIDI data with WildWebMidi with the same score in compressed mode, where the note highlighting would jump around in the score according to the repeats (currently the score can be expanded and the MIDI file is a straight pass through the expanded score).
Here is a test case:
This score would be displayed, but the MIDI file would play the sequence C D C E F F, and the notes would highlight in that sequence. (also there could be another expansion for only second endings, which would produce C E F in the MIDI).
The output timemap for the compressed score is currently (this should probably remain the default if no MIDI expansion is requested):
[ { "tstamp": 0.000000, "qstamp": 0.000000, "tempo": 60, "on": ["note-L7F1"] }, { "tstamp": 4000.000000, "qstamp": 4.000000, "on": ["note-L10F1"], "off": ["note-L7F1"] }, { "tstamp": 8000.000000, "qstamp": 8.000000, "on": ["note-L13F1"], "off": ["note-L10F1"] }, { "tstamp": 12000.000000, "qstamp": 12.000000, "on": ["note-L16F1"], "off": ["note-L13F1"] }, { "tstamp": 16000.000000, "qstamp": 16.000000, "off": ["note-L16F1"] } ]
Here is what the timemap (and matching MIDI file) should be produced if an expanded MIDI file is requested:
[ { "tstamp": 0.000000, // C (note-L7F1) "qstamp": 0.000000, "tempo": 60, "on": ["note-L7F1"] }, { "tstamp": 4000.000000, // D (note-L10F1) "qstamp": 4.000000, "on": ["note-L10F1"], "off": ["note-L7F1"] }, { "tstamp": 8000.000000, // C (note-L7F1) "qstamp": 0.000000, "tempo": 60, "on": ["note-L7F1"], "off": ["note-L10F1"] }, { "tstamp": 12000.000000, // E (note-L13F1) "qstamp": 8.000000, "on": ["note-L13F1"], "off": ["note-L7F1"] }, { "tstamp": 16000.000000, // F (note-L16F1) "qstamp": 12.000000, "on": ["note-L16F1"], "off": ["note-L13F1"] }, { "tstamp": 20000.000000, // F (note-L16F1) "qstamp": 12.000000, "on": ["note-L16F1"], "off": ["note-L16F1"] }, { "tstamp": 24000.000000, // end "qstamp": 16.000000, "off": ["note-L16F1"] } ]
The
tstamp
variable always increased in the timemap (millisecond time in the MIDI file), but theqstamp
will decrease whenever there is a repeat happening.Here is the distilled timemap:
real score 0 0 4000 4 8000 0 12000 8 16000 12 20000 12 24000 16
In the MEI score, the time data would be reversed, with potentially multiple realTime values stored for each note:
score real 0 [0, 8000] 4 [4000] 8 [12000] 12 [16000, 20000]
So for example, the first note would have two realTime values: 0 for the first repeat, and 8000 for the second repeat. Likewise, the note in the last measure at scoreTime 12 would have an array containing the two realTime values 16000 and 20000.
If there were an expansion list for the second endings only, then the score's note would have the values related to the timings of the notes in the shortened MIDI file:
score real 0 [0] 4 [] 8 [4000] 12 [8000]
Notice that the realTime values for the first ending note (D) is never played, so it has an empty realTime.
Test MEI data:
<?xml version="1.0" encoding="UTF-8"?> <?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?> <?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> <mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.0"> <meiHead> <fileDesc> <titleStmt> <title /> </titleStmt> <pubStmt /> </fileDesc> <encodingDesc> <appInfo> <application isodate="2021-02-02T23:23:59" version="3.2.0-dev-8f1ece3-dirty"> <name>Verovio</name> <p>Transcoded from Humdrum</p> </application> </appInfo> </encodingDesc> <workList> <work> <title /> </work> </workList> </meiHead> <music> <body> <mdiv xml:id="mdiv-0000001923652048"> <score xml:id="score-0000001831078766"> <scoreDef xml:id="scoredef-0000001634015516" midi.bpm="60"> <staffGrp xml:id="staffgrp-0000001108141941"> <staffDef xml:id="staffdef-0000000076573858" n="1" lines="5"> <clef xml:id="clef-L2F1" shape="G" line="2" /> <meterSig xml:id="metersig-L3F1" count="4" unit="4" /> </staffDef> </staffGrp> </scoreDef> <section xml:id="section-L1F1"> <expansion plist="#label-A #label-A1 #label-A #label-A2 #label-B #label-B" xml:id="expansion-L4F1" /> <section xml:id="label-A"> <measure xml:id="measure-L1" n="1"> <staff xml:id="staff-0000000685011685" n="1"> <layer xml:id="layer-L1F1N1" n="1"> <note xml:id="note-L7F1" dur="1" oct="4" pname="c" accid.ges="n" /> </layer> </staff> </measure> </section> <ending xml:id="label-A1" n="1"> <measure xml:id="measure-L8" right="rptend" n="2"> <staff xml:id="staff-L8F1N1" n="1"> <layer xml:id="layer-L8F1N1" n="1"> <note xml:id="note-L10F1" dur="1" oct="4" pname="d" accid.ges="n" /> </layer> </staff> </measure> </ending> <ending xml:id="label-A2" n="2"> <measure xml:id="measure-L11" n="3"> <staff xml:id="staff-L11F1N1" n="1"> <layer xml:id="layer-L11F1N1" n="1"> <note xml:id="note-L13F1" dur="1" oct="4" pname="e" accid.ges="n" /> </layer> </staff> </measure> </ending> <section xml:id="label-B"> <measure xml:id="measure-L14" left="rptstart" right="rptend" n="4"> <staff xml:id="staff-L14F1N1" n="1"> <layer xml:id="layer-L14F1N1" n="1"> <note xml:id="note-L16F1" dur="1" oct="4" pname="f" accid.ges="n" /> </layer> </staff> </measure> </section> </section> </score> </mdiv> </body> </music> </mei>
And a test containing a second-ending expansion:
<?xml version="1.0" encoding="UTF-8"?> <?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?> <?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> <mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.0"> <meiHead> <fileDesc> <titleStmt> <title /> </titleStmt> <pubStmt /> </fileDesc> <encodingDesc> <appInfo> <application isodate="2021-02-02T23:23:19" version="3.2.0-dev-8f1ece3-dirty"> <name>Verovio</name> <p>Transcoded from Humdrum</p> </application> </appInfo> </encodingDesc> <workList> <work> <title /> </work> </workList> </meiHead> <music> <body> <mdiv xml:id="mdiv-0000000048699960"> <score xml:id="score-0000001258871766"> <scoreDef xml:id="scoredef-0000001634015516" midi.bpm="60"> <staffGrp xml:id="staffgrp-0000002139912416"> <staffDef xml:id="staffdef-0000000014370509" n="1" lines="5"> <clef xml:id="clef-L2F1" shape="G" line="2" /> <meterSig xml:id="metersig-L3F1" count="4" unit="4" /> </staffDef> </staffGrp> </scoreDef> <section xml:id="section-L1F1"> <choice xml:id="choice-0000001179785592"> <orig xml:id="orig-0000001713763553"> <expansion plist="#label-A #label-A1 #label-A #label-A2 #label-B #label-B" xml:id="expansion-L4F1" /> </orig> <reg xml:id="reg-0000000163708006" type="norep"> <expansion plist="#label-A #label-A2 #label-B" xml:id="expansion-L5F1" type="norep" /> </reg> </choice> <section xml:id="label-A"> <measure xml:id="measure-L1" n="1"> <staff xml:id="staff-0000000725373844" n="1"> <layer xml:id="layer-L1F1N1" n="1"> <note xml:id="note-L8F1" dur="1" oct="4" pname="c" accid.ges="n" /> </layer> </staff> </measure> </section> <ending xml:id="label-A1" n="1"> <measure xml:id="measure-L9" right="rptend" n="2"> <staff xml:id="staff-L9F1N1" n="1"> <layer xml:id="layer-L9F1N1" n="1"> <note xml:id="note-L11F1" dur="1" oct="4" pname="d" accid.ges="n" /> </layer> </staff> </measure> </ending> <ending xml:id="label-A2" n="2"> <measure xml:id="measure-L12" n="3"> <staff xml:id="staff-L12F1N1" n="1"> <layer xml:id="layer-L12F1N1" n="1"> <note xml:id="note-L14F1" dur="1" oct="4" pname="e" accid.ges="n" /> </layer> </staff> </measure> </ending> <section xml:id="label-B"> <measure xml:id="measure-L15" left="rptstart" right="rptend" n="4"> <staff xml:id="staff-L15F1N1" n="1"> <layer xml:id="layer-L15F1N1" n="1"> <note xml:id="note-L17F1" dur="1" oct="4" pname="f" accid.ges="n" /> </layer> </staff> </measure> </section> </section> </score> </mdiv> </body> </music> </mei>
Has there been any new progress on this issue?
Technically this features has now been implemented, since verovio can now expand a score and output a MIDI file (using the
--expand
option).从技术上讲,此功能现已实现,因为 verovio 现在可以扩展乐谱并输出 MIDI 文件(使用--expand
选项)。But a second stage of implementation would be to render an expanded MIDI file while keeping the score in compressed format. This would allow live playback of the MIDI data with WildWebMidi with the same score in compressed mode, where the note highlighting would jump around in the score according to the repeats (currently the score can be expanded and the MIDI file is a straight pass through the expanded score).但实现的第二个阶段是渲染扩展的 MIDI 文件,同时保持乐谱为压缩格式。 这将允许在压缩模式下使用 WildWebMidi 以相同的乐谱实时播放 MIDI 数据,其中音符高亮显示将根据重复在乐谱中跳动(目前乐谱可以扩展,MIDI 文件是直接通过扩展的乐谱)。
Here is a test case:下面是一个测试用例:
This score would be displayed, but the MIDI file would play the sequence C D C E F F, and the notes would highlight in that sequence. (also there could be another expansion for only second endings, which would produce C E F in the MIDI).这个乐谱会被显示出来,但 MIDI 文件会播放音序 C D C E F F,并且音符会在该音序中高亮显示。(也可以有另一个仅针对第二个结尾的扩展,这将在 MIDI 中产生 C E F)。
The output timemap for the compressed score is currently (this should probably remain the default if no MIDI expansion is requested):压缩乐谱的输出时间映射为当前(如果未请求 MIDI 扩展,则可能应保持默认值):
[ { "tstamp": 0.000000, "qstamp": 0.000000, "tempo": 60, "on": ["note-L7F1"] }, { "tstamp": 4000.000000, "qstamp": 4.000000, "on": ["note-L10F1"], "off": ["note-L7F1"] }, { "tstamp": 8000.000000, "qstamp": 8.000000, "on": ["note-L13F1"], "off": ["note-L10F1"] }, { "tstamp": 12000.000000, "qstamp": 12.000000, "on": ["note-L16F1"], "off": ["note-L13F1"] }, { "tstamp": 16000.000000, "qstamp": 16.000000, "off": ["note-L16F1"] } ]
Here is what the timemap (and matching MIDI file) should be produced if an expanded MIDI file is requested:如果请求扩展的 MIDI 文件,则应生成时间映射(和匹配的 MIDI 文件)如下:
[ { "tstamp": 0.000000, // C (note-L7F1) "qstamp": 0.000000, "tempo": 60, "on": ["note-L7F1"] }, { "tstamp": 4000.000000, // D (note-L10F1) "qstamp": 4.000000, "on": ["note-L10F1"], "off": ["note-L7F1"] }, { "tstamp": 8000.000000, // C (note-L7F1) "qstamp": 0.000000, "tempo": 60, "on": ["note-L7F1"], "off": ["note-L10F1"] }, { "tstamp": 12000.000000, // E (note-L13F1) "qstamp": 8.000000, "on": ["note-L13F1"], "off": ["note-L7F1"] }, { "tstamp": 16000.000000, // F (note-L16F1) "qstamp": 12.000000, "on": ["note-L16F1"], "off": ["note-L13F1"] }, { "tstamp": 20000.000000, // F (note-L16F1) "qstamp": 12.000000, "on": ["note-L16F1"], "off": ["note-L16F1"] }, { "tstamp": 24000.000000, // end "qstamp": 16.000000, "off": ["note-L16F1"] } ]
The
tstamp
variable always increased in the timemap (millisecond time in the MIDI file), but theqstamp
will decrease whenever there is a repeat happening.tstamp
变量在时间映射中总是增加(MIDI 文件中的毫秒时间),但每当有重复发生时,qstamp
就会减少。Here is the distilled timemap:以下是提炼的时间表:
real score 0 0 4000 4 8000 0 12000 8 16000 12 20000 12 24000 16
In the MEI score, the time data would be reversed, with potentially multiple realTime values stored for each note:在 MEI 分数中,时间数据将被反转,每个音符可能存储多个 realTime 值:
score real 0 [0, 8000] 4 [4000] 8 [12000] 12 [16000, 20000]
So for example, the first note would have two realTime values: 0 for the first repeat, and 8000 for the second repeat. Likewise, the note in the last measure at scoreTime 12 would have an array containing the two realTime values 16000 and 20000.例如,第一个音符将有两个 realTime 值:0 表示第一次重复,8000 表示第二次重复。 同样,scoreTime 12 处最后一个小节中的注释将具有一个包含两个 realTime 值 16000 和 20000 的数组。
If there were an expansion list for the second endings only, then the score's note would have the values related to the timings of the notes in the shortened MIDI file:如果只有第二个结尾的扩展列表,那么乐谱的音符将具有与缩短的 MIDI 文件中音符的时间相关的值:
score real 0 [0] 4 [] 8 [4000] 12 [8000]
Notice that the realTime values for the first ending note (D) is never played, so it has an empty realTime.请注意,第一个结束音符 (D) 的 realTime 值从未播放过,因此它的 realTime 为空。
Test MEI data: 测试 FROM 数据:
<?xml version="1.0" encoding="UTF-8"?> <?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?> <?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> <mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.0"> <meiHead> <fileDesc> <titleStmt> <title /> </titleStmt> <pubStmt /> </fileDesc> <encodingDesc> <appInfo> <application isodate="2021-02-02T23:23:59" version="3.2.0-dev-8f1ece3-dirty"> <name>Verovio</name> <p>Transcoded from Humdrum</p> </application> </appInfo> </encodingDesc> <workList> <work> <title /> </work> </workList> </meiHead> <music> <body> <mdiv xml:id="mdiv-0000001923652048"> <score xml:id="score-0000001831078766"> <scoreDef xml:id="scoredef-0000001634015516" midi.bpm="60"> <staffGrp xml:id="staffgrp-0000001108141941"> <staffDef xml:id="staffdef-0000000076573858" n="1" lines="5"> <clef xml:id="clef-L2F1" shape="G" line="2" /> <meterSig xml:id="metersig-L3F1" count="4" unit="4" /> </staffDef> </staffGrp> </scoreDef> <section xml:id="section-L1F1"> <expansion plist="#label-A #label-A1 #label-A #label-A2 #label-B #label-B" xml:id="expansion-L4F1" /> <section xml:id="label-A"> <measure xml:id="measure-L1" n="1"> <staff xml:id="staff-0000000685011685" n="1"> <layer xml:id="layer-L1F1N1" n="1"> <note xml:id="note-L7F1" dur="1" oct="4" pname="c" accid.ges="n" /> </layer> </staff> </measure> </section> <ending xml:id="label-A1" n="1"> <measure xml:id="measure-L8" right="rptend" n="2"> <staff xml:id="staff-L8F1N1" n="1"> <layer xml:id="layer-L8F1N1" n="1"> <note xml:id="note-L10F1" dur="1" oct="4" pname="d" accid.ges="n" /> </layer> </staff> </measure> </ending> <ending xml:id="label-A2" n="2"> <measure xml:id="measure-L11" n="3"> <staff xml:id="staff-L11F1N1" n="1"> <layer xml:id="layer-L11F1N1" n="1"> <note xml:id="note-L13F1" dur="1" oct="4" pname="e" accid.ges="n" /> </layer> </staff> </measure> </ending> <section xml:id="label-B"> <measure xml:id="measure-L14" left="rptstart" right="rptend" n="4"> <staff xml:id="staff-L14F1N1" n="1"> <layer xml:id="layer-L14F1N1" n="1"> <note xml:id="note-L16F1" dur="1" oct="4" pname="f" accid.ges="n" /> </layer> </staff> </measure> </section> </section> </score> </mdiv> </body> </music> </mei>
And a test containing a second-ending expansion:以及一个包含第二个结尾扩展的测试:
<?xml version="1.0" encoding="UTF-8"?> <?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?> <?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> <mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.0"> <meiHead> <fileDesc> <titleStmt> <title /> </titleStmt> <pubStmt /> </fileDesc> <encodingDesc> <appInfo> <application isodate="2021-02-02T23:23:19" version="3.2.0-dev-8f1ece3-dirty"> <name>Verovio</name> <p>Transcoded from Humdrum</p> </application> </appInfo> </encodingDesc> <workList> <work> <title /> </work> </workList> </meiHead> <music> <body> <mdiv xml:id="mdiv-0000000048699960"> <score xml:id="score-0000001258871766"> <scoreDef xml:id="scoredef-0000001634015516" midi.bpm="60"> <staffGrp xml:id="staffgrp-0000002139912416"> <staffDef xml:id="staffdef-0000000014370509" n="1" lines="5"> <clef xml:id="clef-L2F1" shape="G" line="2" /> <meterSig xml:id="metersig-L3F1" count="4" unit="4" /> </staffDef> </staffGrp> </scoreDef> <section xml:id="section-L1F1"> <choice xml:id="choice-0000001179785592"> <orig xml:id="orig-0000001713763553"> <expansion plist="#label-A #label-A1 #label-A #label-A2 #label-B #label-B" xml:id="expansion-L4F1" /> </orig> <reg xml:id="reg-0000000163708006" type="norep"> <expansion plist="#label-A #label-A2 #label-B" xml:id="expansion-L5F1" type="norep" /> </reg> </choice> <section xml:id="label-A"> <measure xml:id="measure-L1" n="1"> <staff xml:id="staff-0000000725373844" n="1"> <layer xml:id="layer-L1F1N1" n="1"> <note xml:id="note-L8F1" dur="1" oct="4" pname="c" accid.ges="n" /> </layer> </staff> </measure> </section> <ending xml:id="label-A1" n="1"> <measure xml:id="measure-L9" right="rptend" n="2"> <staff xml:id="staff-L9F1N1" n="1"> <layer xml:id="layer-L9F1N1" n="1"> <note xml:id="note-L11F1" dur="1" oct="4" pname="d" accid.ges="n" /> </layer> </staff> </measure> </ending> <ending xml:id="label-A2" n="2"> <measure xml:id="measure-L12" n="3"> <staff xml:id="staff-L12F1N1" n="1"> <layer xml:id="layer-L12F1N1" n="1"> <note xml:id="note-L14F1" dur="1" oct="4" pname="e" accid.ges="n" /> </layer> </staff> </measure> </ending> <section xml:id="label-B"> <measure xml:id="measure-L15" left="rptstart" right="rptend" n="4"> <staff xml:id="staff-L15F1N1" n="1"> <layer xml:id="layer-L15F1N1" n="1"> <note xml:id="note-L17F1" dur="1" oct="4" pname="f" accid.ges="n" /> </layer> </staff> </measure> </section> </section> </score> </mdiv> </body> </music> </mei>
how could i add code like this <expansion plist="#label-A #label-A1 #label-A #label-A2 #label-B #label-B" xml:id="expansion-L4F1" />
in MEI file to use expand: "expansion-L4F1"
in option
. i generate a mei file from a xml file
Here is a basic example with one possiblility for adding an expansion list. Ideally the MusicXML-to-MEI converter would automatically generate <expansion>
if it detects <ending>
in the output MEI data (particularly since more complicated cases are possible, such as nested <section>
elements.
When there are multiple measures before an <ending>
, then the converter would ideally place the preceding measures in a <section>
to make generation of <expansion>
easier (i.e., use the ID for the section in the expansion list instead of haing to give every since measure ID in the @plist
).
Musical notation for example:
Conversion of the MusicXML to MEI using verovio:
Transcoded from MusicXML
Now here is an example HTML file with javascript code to add the expansion list:
The script adds the element:
<expansion plist="#m1pww2dk #m8m3bh4 #m1pww2dk #myzr5yh" xml:id="expansionList1"/>
to the final MEI data:
Transcoded from MusicXML
Hello,
Regarding this repeated issue, I found that using the test based on the above method works in most cases. The test case score works fine, but the issue arises when I switch to another score with repetitions. For more complex scores, I encounter the error "@plist could not match the target, MRpt produces empty MIDI output". Could you please advise on how to solve this problem? From my understanding, you extend the repetition by labeling it with time. What elements' IDs should be included in the plist to correctly format the timing?
Thank you!
Here is a longer example (which @rettinghaus and/or @lpugin can comment further on):
Transcoded from Humdrum
The expansion list is:
<expansion plist="#label-A #label-A1 #label-A #label-A2 #label-B" xml:id="expansion-L2F1" />
ID | element | measures |
---|---|---|
label-A |
<section> |
1–3 |
label-A1 |
<ending> |
4–5 |
label-A2 |
<ending> |
6–7 |
label-B |
<section> |
8–9 |
The section with the ID label-A
contains four children elements:
<measure xml:id="measure-L1" right="dbl" n="1">
<scoreDef xml:id="s1o94igl">
<measure xml:id="measure-L7" n="2">
<measure xml:id="measure-L11" n="3">
The section element with ID label-A
is optional and is used to group these four elements. Instead of
plist="#label-A #label-A1 #label-A #label-A2 #label-B"
you could replace #label-A
with the IDREFs of the four children of #label-A
(or if they were not contained in a section element):
plist="#measure-L1 #s1o94igl #measure-L7 #measure-L11 #label-A1 #label-A #label-A2 #label-B"
What elements' IDs should be included in the plist to correctly format the timing?
So it is the IDs (IDREFs technically, which are the IDs with #
in front of the ID) in the order that you want to play the music.
From my understanding, you extend the repetition by labeling it with time.
I don't understand this sentence, so maybe a source of the problem. The expansion list defines a sequence of elements to follow when generating the MIDI. It should be the responsibility of verovio to keep track of the timing information for the generated MIDI. The expansion list only gives the sequence of elements that are to be placed in then given sequence in the MIDI export.
I encounter the error
@Plist
could not match the target,MRpt
produces empty MIDI output".
This could be a separate problem. You have an <mRpt>
in the score? And is there a @plist
in the <mRpt>
or rather in <expansion>
? The error seems to say that an IDREF in @plist
cannot match to an ID in the score.
A possible problem is that in @plist
the IDREFs have to start with #
and for @xml:id
the IDs cannot start with #
.
Based on my current understanding, in the expansion plist, I can place the measure IDs to customize the arrangement timing. So what I need to do is to add my own logic for arranging the timing points and then order the measure IDs accordingly, right?
My current understanding is that the first #id in the plist represents the starting measure, and it will insert the subsequent measures for playback. Each time, I just need to include the id of the starting measure of the repetition as well as the subsequent logic. This is my current understanding. Below is my manually edited mei file。
<?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="m76pxkx">
<fileDesc xml:id="fo8kuxb">
<titleStmt xml:id="tttie9n">
<title>未命名乐谱</title>
<respStmt>
<persName role="composer">作曲 / 编排</persName>
</respStmt>
</titleStmt>
<pubStmt xml:id="p1s5f9vl">
<date isodate="2024-09-12" type="encoding-date">2024-09-12</date>
</pubStmt>
</fileDesc>
<encodingDesc xml:id="e1v0tw7w">
<appInfo xml:id="algonnu">
<application xml:id="a16fokqu" isodate="2024-09-12T17:42:17" version="4.2.0-8a772f5">
<name xml:id="n1sow6rt">Verovio</name>
<p xml:id="py5p0zb">Transcoded from MusicXML</p>
</application>
</appInfo>
</encodingDesc>
</meiHead>
<music>
<body>
<mdiv xml:id="mk00qk6">
<score xml:id="s1z8311">
<scoreDef xml:id="s15wkvd7">
<staffGrp xml:id="skd1am9">
<staffGrp xml:id="P1" bar.thru="true">
<grpSym xml:id="gepw1h5" symbol="brace" />
<label xml:id="l1qdmni4">Piano</label>
<instrDef xml:id="itlwcav" midi.channel="0" midi.instrnum="0"
midi.volume="78.00%" />
<staffDef xml:id="s99n7kx" n="1" lines="5" ppq="1">
<clef xml:id="cdwgbjf" shape="G" line="2" />
<keySig xml:id="k1uwof91" sig="0" />
<meterSig xml:id="mkkpgq1" count="4" unit="4" />
</staffDef>
<staffDef xml:id="s1ijhfb4" n="2" lines="5" ppq="1">
<clef xml:id="c6n40zb" shape="F" line="4" />
<keySig xml:id="k1tie4si" sig="0" />
<meterSig xml:id="m1a9zja7" count="4" unit="4" />
</staffDef>
</staffGrp>
</staffGrp>
</scoreDef>
<section xml:id="silgj4m">
<expansion
plist="#m11eyy6j #m11eyy6j #m11eyy6j #m11eyy6j #m11eyy6j #m11eyy6j #mg074no #mg074no #mg074no"
xml:id="expansionList1" />
<pb xml:id="p96mkud" />
<measure xml:id="m11eyy6j" n="1">
<staff xml:id="s9r46e7" n="1">
<layer xml:id="l7etlqn" n="1">
<note xml:id="nr5vl6k" dur.ppq="2" dur="2" oct="4" pname="b"
stem.dir="down" />
<note xml:id="n1a32dcj" dur.ppq="2" dur="2" oct="4" pname="f"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="sizh49p" n="2">
<layer xml:id="l1ornha7" n="5">
<mRest xml:id="mbq0k4k" />
</layer>
</staff>
</measure>
<measure xml:id="my5tisq" n="2">
<staff xml:id="s1q8cnvm" n="1">
<layer xml:id="lfxtx7p" n="1">
<note xml:id="nn7woys" dur.ppq="2" dur="2" oct="4" pname="g"
stem.dir="up" />
<note xml:id="n10gvfbm" dur.ppq="2" dur="2" oct="4" pname="d"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="s2vvewp" n="2">
<layer xml:id="l1jffgsu" n="5">
<mRest xml:id="mncp183" />
</layer>
</staff>
</measure>
<measure xml:id="m2u4e6v" n="3">
<staff xml:id="s1k54crm" n="1">
<layer xml:id="lgt5nfk" n="1">
<note xml:id="n17kgq2j" dur.ppq="2" dur="2" oct="4" pname="e"
stem.dir="up" />
<rest xml:id="rddvosx" dur.ppq="2" dur="2" />
</layer>
</staff>
<staff xml:id="sccgpde" n="2">
<layer xml:id="l14mczpi" n="5">
<mRest xml:id="ma9mlq6" />
</layer>
</staff>
</measure>
<measure xml:id="mr6yjs" n="4">
<staff xml:id="s1epucul" n="1">
<layer xml:id="lejg45g" n="1">
<note xml:id="nb5ko7w" dur.ppq="2" dur="2" oct="4" pname="b"
stem.dir="down" />
<note xml:id="n151gavc" dur.ppq="2" dur="2" oct="4" pname="e"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="s1aj2wqa" n="2">
<layer xml:id="lq3xzpz" n="5">
<mRest xml:id="mw09kh2" />
</layer>
</staff>
</measure>
<measure xml:id="m1yvircq" right="rptend" n="5">
<staff xml:id="s18xzaii" n="1">
<layer xml:id="ldi66z" n="1">
<note xml:id="n1se27cg" dur.ppq="4" dur="1" oct="4" pname="c" />
</layer>
</staff>
<staff xml:id="s2v3jgc" n="2">
<layer xml:id="l18ixaaf" n="5">
<mRest xml:id="m151phc4" />
</layer>
</staff>
</measure>
<measure xml:id="m64505m" n="6">
<staff xml:id="slom3xj" n="1">
<layer xml:id="lft74cn" n="1">
<note xml:id="n1v6gb4x" dur.ppq="1" dur="4" oct="4" pname="g"
stem.dir="up" />
<note xml:id="n1c2eaz3" dur.ppq="1" dur="4" oct="4" pname="a"
stem.dir="up" />
<note xml:id="n1iwmqhu" dur.ppq="1" dur="4" oct="4" pname="b"
stem.dir="down" />
<note xml:id="n1gro224" dur.ppq="1" dur="4" oct="5" pname="c"
stem.dir="down" />
</layer>
</staff>
<staff xml:id="sdywnrf" n="2">
<layer xml:id="l3dbfpg" n="5">
<mRest xml:id="m18t0nj1" />
</layer>
</staff>
</measure>
<measure xml:id="me3gdtf" n="7">
<staff xml:id="s1lz5k3d" n="1">
<layer xml:id="l1kug4rp" n="1">
<note xml:id="nv15y1x" dur.ppq="1" dur="4" oct="4" pname="e"
stem.dir="up" />
<rest xml:id="r1vl1hu4" dur.ppq="1" dur="4" />
<note xml:id="nlww67x" dur.ppq="1" dur="4" oct="5" pname="c"
stem.dir="down" />
<rest xml:id="rylxnhv" dur.ppq="1" dur="4" />
</layer>
</staff>
<staff xml:id="s21x2or" n="2">
<layer xml:id="l1v92ngh" n="5">
<mRest xml:id="m1novkf2" />
</layer>
</staff>
</measure>
<measure xml:id="m1zw7b6" n="8">
<staff xml:id="s1kv5iz2" n="1">
<layer xml:id="l1f2w0bi" n="1">
<note xml:id="nyc04hk" dur.ppq="2" dur="2" oct="4" pname="f"
stem.dir="up" />
<note xml:id="nos5uab" dur.ppq="2" dur="2" oct="4" pname="d"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="shbksax" n="2">
<layer xml:id="l186ynek" n="5">
<mRest xml:id="m1n5ii4s" />
</layer>
</staff>
</measure>
<sb xml:id="s1050vw3" />
<measure xml:id="moq0bdz" n="9">
<staff xml:id="shzkn5m" n="1">
<layer xml:id="l1hvzxtf" n="1">
<note xml:id="n1v6h4ey" dur.ppq="2" dur="2" oct="5" pname="c"
stem.dir="down" />
<note xml:id="ngdnyd0" dur.ppq="2" dur="2" oct="4" pname="g"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="ssyw926" n="2">
<layer xml:id="ls1e0di" n="5">
<mRest xml:id="m1os0s5c" />
</layer>
</staff>
</measure>
<measure xml:id="mg074no" left="rptstart" n="10">
<staff xml:id="s1og9psn" n="1">
<layer xml:id="l17cbp1p" n="1">
<note xml:id="n2rxcda" dur.ppq="2" dur="2" oct="4" pname="f"
stem.dir="up" />
<note xml:id="nm7u2o4" dur.ppq="2" dur="2" oct="4" pname="a"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="sql2yei" n="2">
<layer xml:id="l7cwzbg" n="5">
<mRest xml:id="mnka4ly" />
</layer>
</staff>
</measure>
<measure xml:id="m1qwofec" n="11">
<staff xml:id="s1k23pp8" n="1">
<layer xml:id="lni10xv" n="1">
<note xml:id="n1daize9" dur.ppq="2" dur="2" oct="4" pname="f"
stem.dir="up" />
<note xml:id="n1aejsfk" dur.ppq="2" dur="2" oct="4" pname="e"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="s8ra62q" n="2">
<layer xml:id="l13h7wg4" n="5">
<mRest xml:id="mc1dcwg" />
</layer>
</staff>
</measure>
<measure xml:id="m48llki" n="12">
<staff xml:id="ssbb9rg" n="1">
<layer xml:id="l8s7p33" n="1">
<note xml:id="n4tm46x" dur.ppq="2" dur="2" oct="4" pname="d"
stem.dir="up" />
<note xml:id="n1xw6n6f" dur.ppq="2" dur="2" oct="3" pname="g"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="s1vzy0gq" n="2">
<layer xml:id="l1bczxoe" n="5">
<mRest xml:id="m1cc7c9j" />
</layer>
</staff>
</measure>
<measure xml:id="m1dgmvg5" n="13">
<staff xml:id="s14jq1mi" n="1">
<layer xml:id="lrnltkp" n="1">
<note xml:id="nk7qjyh" dur.ppq="2" dur="2" oct="4" pname="c"
stem.dir="up" />
<rest xml:id="rbtbn5q" dur.ppq="2" dur="2" />
</layer>
</staff>
<staff xml:id="swg4nlz" n="2">
<layer xml:id="lahdhwq" n="5">
<mRest xml:id="m2mhwu3" />
</layer>
</staff>
</measure>
<measure xml:id="mvr9jgs" n="14">
<staff xml:id="s1y66rc1" n="1">
<layer xml:id="l16zlw0k" n="1">
<note xml:id="nb8fy2x" dur.ppq="2" dur="2" oct="4" pname="f"
stem.dir="up" />
<rest xml:id="r13z51of" dur.ppq="2" dur="2" />
</layer>
</staff>
<staff xml:id="s1mjff2f" n="2">
<layer xml:id="l16pisja" n="5">
<mRest xml:id="m6n9ug8" />
</layer>
</staff>
</measure>
<measure xml:id="mdcryi3" n="15">
<staff xml:id="s12e9mii" n="1">
<layer xml:id="l1vn6x" n="1">
<chord xml:id="c10221px" dur.ppq="2" dur="2" stem.dir="up">
<note xml:id="n11pvp6m" oct="3" pname="a" />
<note xml:id="n11g6wap" oct="4" pname="c" />
</chord>
<rest xml:id="rwjfsmk" dur.ppq="2" dur="2" />
</layer>
</staff>
<staff xml:id="s17w0k4k" n="2">
<layer xml:id="l14yk48j" n="5">
<mRest xml:id="mxhh29d" />
</layer>
</staff>
</measure>
<ending xml:id="e9gwc42" lendsym="angledown" n="1.">
<measure xml:id="m8qeyo1" right="rptend" n="16">
<staff xml:id="su57hff" n="1">
<layer xml:id="l1vzip2" n="1">
<note xml:id="nrd8prp" dur.ppq="2" dur="2" oct="4" pname="f"
stem.dir="up" />
<note xml:id="nkhpaki" dur.ppq="2" dur="2" oct="4" pname="a"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="sv11nb8" n="2">
<layer xml:id="lxqytq" n="5">
<mRest xml:id="mnxegnx" />
</layer>
</staff>
</measure>
</ending>
<ending xml:id="e12poiib" lendsym="angledown" n="2.">
<measure xml:id="m17ahtnj" n="17">
<staff xml:id="s19eexq5" n="1">
<layer xml:id="l1o9zw64" n="1">
<note xml:id="n1ec1urh" dur.ppq="2" dur="2" oct="4"
pname="a" stem.dir="up" />
<note xml:id="n12ya71g" dur.ppq="2" dur="2" oct="4"
pname="g" stem.dir="up" />
</layer>
</staff>
<staff xml:id="s18penv9" n="2">
<layer xml:id="lntio15" n="5">
<mRest xml:id="m11bg0sc" />
</layer>
</staff>
</measure>
</ending>
<sb xml:id="s1rpjcs8" />
<measure xml:id="m1ka0ql" n="18">
<staff xml:id="sjrvu87" n="1">
<layer xml:id="l1oev7iw" n="1">
<note xml:id="nrx0brd" dur.ppq="1" dur="4" oct="4" pname="e"
stem.dir="up" />
<chord xml:id="c1pwhcjw" dur.ppq="1" dur="4" stem.dir="up">
<note xml:id="nvv6nbu" oct="4" pname="g" />
<note xml:id="n1e4s3qr" oct="4" pname="b" />
</chord>
<note xml:id="nquwjje" dur.ppq="1" dur="4" oct="5" pname="c"
stem.dir="down" />
<note xml:id="n1nlremo" dur.ppq="1" dur="4" oct="4" pname="f"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="sxbqg3b" n="2">
<layer xml:id="l1xl9pvg" n="5">
<mRest xml:id="m1fqib2i" />
</layer>
</staff>
</measure>
<measure xml:id="mx2e8hf" left="rptstart" n="19">
<staff xml:id="s1geca8d" n="1">
<layer xml:id="l6zigoe" n="1">
<note xml:id="nnr53u8" dur.ppq="1" dur="4" oct="4" pname="d"
stem.dir="up" />
<note xml:id="n13szarq" dur.ppq="1" dur="4" oct="4" pname="b"
stem.dir="down" />
<note xml:id="n1xtr5it" dur.ppq="1" dur="4" oct="4" pname="f"
stem.dir="up" />
<note xml:id="n2jpfj8" dur.ppq="1" dur="4" oct="4" pname="b"
stem.dir="down" />
</layer>
</staff>
<staff xml:id="stf1yy9" n="2">
<layer xml:id="le8pdqh" n="5">
<mRest xml:id="m1xkn1md" />
</layer>
</staff>
</measure>
<measure xml:id="m1vt80k7" n="20">
<staff xml:id="ss4ml1d" n="1">
<layer xml:id="lb7qsvq" n="1">
<chord xml:id="c8kah6t" dur.ppq="1" dur="4" stem.dir="down">
<note xml:id="n12w5jf" oct="4" pname="g" />
<note xml:id="nkp02f2" oct="5" pname="d" />
</chord>
<note xml:id="n96rzdt" dur.ppq="1" dur="4" oct="4" pname="g"
stem.dir="up" />
<note xml:id="n76i0f9" dur.ppq="1" dur="4" oct="4" pname="g"
stem.dir="up" />
<note xml:id="n15ik2ft" dur.ppq="1" dur="4" oct="4" pname="d"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="s18ii0qj" n="2">
<layer xml:id="l150rz64" n="5">
<mRest xml:id="m172j0t4" />
</layer>
</staff>
</measure>
<measure xml:id="m1h50en2" n="21">
<staff xml:id="s1vsursq" n="1">
<layer xml:id="l1o69wi9" n="1">
<note xml:id="n10naygy" dur.ppq="1" dur="4" oct="4" pname="f"
stem.dir="up" />
<note xml:id="nf97mn" dur.ppq="1" dur="4" oct="4" pname="g"
stem.dir="up" />
<chord xml:id="c1upfpl" dur.ppq="1" dur="4" stem.dir="up">
<note xml:id="n1gdj94m" oct="4" pname="c" />
<note xml:id="n1w5sj10" oct="4" pname="g" />
<note xml:id="nk4kl0i" oct="5" pname="c" />
</chord>
<note xml:id="n7ljqku" dur.ppq="1" dur="4" oct="3" pname="b"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="s2ov1y3" n="2">
<layer xml:id="ld4kp3o" n="5">
<mRest xml:id="m17f0mgn" />
</layer>
</staff>
</measure>
<ending xml:id="e1ujlge1" lendsym="angledown" n="1.">
<measure xml:id="m1y3ut2m" right="rptend" n="22">
<staff xml:id="savs2xs" n="1">
<layer xml:id="lvxyu52" n="1">
<note xml:id="n1x3n6ci" dur.ppq="1" dur="4" oct="4"
pname="g" stem.dir="up" />
<rest xml:id="rxcbl80" dur.ppq="1" dur="4" />
<note xml:id="n1m8y7oj" dur.ppq="1" dur="4" oct="4"
pname="d" stem.dir="up" />
<rest xml:id="r165omxr" dur.ppq="1" dur="4" />
</layer>
</staff>
<staff xml:id="srqzwgt" n="2">
<layer xml:id="l14hjqm3" n="5">
<mRest xml:id="mltdvcv" />
</layer>
</staff>
</measure>
</ending>
<ending xml:id="e1laxevk" lendsym="none" n="2.">
<measure xml:id="maovs9" n="23">
<staff xml:id="s1j8c4om" n="1">
<layer xml:id="lue2q5r" n="1">
<note xml:id="nbkx3ma" dur.ppq="1" dur="4" oct="4" pname="g"
stem.dir="up" />
<note xml:id="nmacf42" dur.ppq="1" dur="4" oct="4" pname="e"
stem.dir="up" />
<note xml:id="n1t3t1d7" dur.ppq="1" dur="4" oct="4"
pname="e" stem.dir="up" />
<note xml:id="n1criqod" dur.ppq="1" dur="4" oct="4"
pname="c" stem.dir="up" />
</layer>
</staff>
<staff xml:id="sv59hrb" n="2">
<layer xml:id="lqa9pha" n="5">
<mRest xml:id="m5fkbmr" />
</layer>
</staff>
</measure>
</ending>
<measure xml:id="mzizxej" n="24">
<staff xml:id="s10tyx3d" n="1">
<layer xml:id="l3cve2y" n="1">
<note xml:id="ny5qiqw" dur.ppq="1" dur="4" oct="3" pname="b"
stem.dir="up" />
<note xml:id="n1eszsm0" dur.ppq="1" dur="4" oct="3" pname="a"
stem.dir="up" />
<note xml:id="ng6u5im" dur.ppq="1" dur="4" oct="3" pname="g"
stem.dir="up" />
<note xml:id="n1f4j47a" dur.ppq="1" dur="4" oct="3" pname="a"
stem.dir="up" />
</layer>
</staff>
<staff xml:id="s1g4f1or" n="2">
<layer xml:id="l1ch4xez" n="5">
<mRest xml:id="m9v9kww" />
</layer>
</staff>
</measure>
<sb xml:id="s16lhbdg" />
<measure xml:id="mr5tche" right="end" n="25">
<staff xml:id="s1wdz96k" n="1">
<layer xml:id="l1u39b9c" n="1">
<note xml:id="nxyb0ww" dur.ppq="4" dur="1" oct="4" pname="c" />
</layer>
</staff>
<staff xml:id="shirdx3" n="2">
<layer xml:id="l14q1tbd" n="5">
<mRest xml:id="m49q0pj" />
</layer>
</staff>
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
My understanding is that it will play #m11eyy6j six times and then execute my #mg074no three times at the beginning of the next repetition. The purpose of this seems to be to modify the timing logic of the repetitions, correct?
OK, I understand the sentence now.
When I try to export a timemap from my slightly longer example that contains an <expansion>
element, I am getting the error you are mentioning:
[Warning] 5 element(s) with a @plist could not match the target
Output written to example.json.
And the output example.json
contains the non-expanded sequence of the score. In other words, verovio is producing the expected timemap output, so I don't understand why the warning is/should be displayed.
If I remove the <expansion>
element there is no warning printed (and I get the same output timemap as expected).
@rettinghaus and/or @lpugin could comment on if my placement of the <expansion>
element in the data is correct.
When I try to apply the expansion with the command-line version of verovio to export the timemap:
verovio --expand expansion-L2F1 -t timemap example.mei
I get the same warning:
[Warning] 5 element(s) with a @plist could not match the target
Output written to example.json.
And the expansion list was ignored (the measures are in score order from 1 through 9, not [1,2,3,4,5,1,2,3,6,7,8,9]
.
When using the --expand
option to create an SVG it is working:
(although this output is not useful to look at since an expanded visual score should remove the repeat barlines and remove the endings to be of any practical use, and note the complication with the key change I added).
So while --expand
is implemented for generating SVG output from verovio, it is not implemented for timemap output from verovio (and by extension MIDI). Timemaps are created at the same time as MIDI generation (as I remember) so this relates to the subject of the issue, which is that repetitions are not implemented from <expansion>
yet when generating MIDI output from verovio.
Implementing this externally from verovio would be more complicated than implementing it inside of verovio. You could expand the <expansion>
list to create MEI data with the desired repeats, but there would be two problems (1) the MEI data would have identical IDs for the repeated music, and (2) if you were to fix this, highlighting the notes in the SVG score would not work for at least one repetition.
Hello, I'm encountering an issue with repeats. When I transpose to other keys, such as C or F,, it shows me
When I set my plist length to 70, it can render successfully on the second attempt, but if it exceeds that, an error occurs. This is my logic for handling repeats.
```javascript const setExpansionInMEIXml = scoreData => { const parser = new DOMParser(); const xmlDoc = parser.parseFromString(scoreData, 'application/xml'); const rootElement = xmlDoc.documentElement; let plist = []; const firstMeasure = xmlDoc.querySelector('measure[n]'); const measures = xmlDoc.querySelectorAll('measure[n]'); const endMeasure = measures[measures.length - 1]; const startMeasureArr = Array.from(xmlDoc.querySelectorAll('measure[left="rptstart"]')); const endMeasureArr = Array.from(xmlDoc.querySelectorAll('measure[right="rptend"]')); const allMeasures = Array.from(xmlDoc.querySelectorAll('measure[n]')); const startMeasureNumber = startMeasureArr[0]?.getAttribute('n'); const endMeasureNumber = endMeasureArr[0]?.getAttribute('n'); const startNumber = startMeasureArr[startMeasureArr.length - 1 >= 0 ? startMeasureArr.length - 1 : 0]?.getAttribute('n'); const endNumber = endMeasureArr[endMeasureArr.length - 1 >= 0 ? endMeasureArr.length - 1 : 0]?.getAttribute('n'); const bol = startMeasureArr.length !== endMeasureArr.length; if (bol) { if (endMeasureNumber && startMeasureNumber && startMeasureNumber > endMeasureNumber) { startMeasureArr.unshift(firstMeasure); } if (startNumber && (endNumber < startNumber || !endNumber)) { endMeasureArr.push(endMeasure); } } for (let i = 0; i < startMeasureArr.length; i++) { const noEndingArr = []; const hasEndingArr = []; const first = parseInt(startMeasureArr[i].getAttribute('n')); const end = parseInt(endMeasureArr[i].getAttribute('n')); for (let index = first; index <= end; index++) { const measure = xmlDoc.querySelector(`measure[n="${index}"]`); if (measure.parentNode.tagName !== 'ending') { noEndingArr.push(`#${measure.getAttribute('xml:id')}`); hasEndingArr.push(`#${measure.getAttribute('xml:id')}`); } else { const id = `#${measure.parentNode.getAttribute('xml:id')}`; if (!noEndingArr.includes(id)) { let ending = null; let nextDom = measure.parentNode; let num = 0; const number = parseInt(measure.parentNode.getAttribute('n').split('')[0]); while (!ending && num < 50) { nextDom = nextDom?.nextElementSibling; if (nextDom && nextDom?.tagName === 'ending') { ending = nextDom; } num++; } noEndingArr.push(id); if (ending) { const nextNumber = parseInt(ending.getAttribute('n').split('')[0]); if (nextNumber - number == 1) { const endingId = `#${nextDom.getAttribute('xml:id')}`; hasEndingArr.push(endingId); } } } } } plist.push(...noEndingArr); plist.push(...hasEndingArr); } const expansionElement = xmlDoc.createElementNS(rootElement.namespaceURI, 'expansion'); expansionElement.setAttribute('plist', plist.join(' ')); expansionElement.setAttribute('xml:id', 'expansion-full'); const meiNamespace = rootElement.namespaceURI; const targetSection = xmlDoc.getElementsByTagNameNS(meiNamespace, 'section')[0]; if (targetSection) { targetSection.insertBefore(expansionElement, targetSection.firstChild); } const serializer = new XMLSerializer(); const updatedMeiString = serializer.serializeToString(xmlDoc); return updatedMeiString; }; ```
On Sarfira, I’m also experiencing a memory overflow issue after refreshing the page multiple times. Normally, the renderer's page memory usage fluctuates between 1.2 GB and 2.2 GB, but after multiple refreshes, it reaches over 3 GB, and rendering fails. What could be causing this?
Diagnosing a memory leak without seeing all the code in your application is almost impossible to do. I would suggest using the browser's memory profiling tools to see if you can find out where it's going wrong.
Here is my code. I didn’t add any extra content; I only generated the image, yet it still became bloated. This is my code. After refreshing 5 times on an Sarfira , the memory usage increases even more.
```javascript
I'm not very familiar with C++ code, and I've spent a long time analyzing it with debugging tools but haven’t pinpointed the issue. How should I go about solving this?
Here’s the memory timeline screenshot I captured.
Under normal circumstances.
No problem for me with Safari Version 18.0.1 (20619.1.26.31.7). Your memory usage looks very weird.
Is there a way of encoding repeats in MEI which verovio, and more particularly the verovio MIDI export understands?
Example work with one simple repeat (no separate second ending): http://verovio.humdrum.org/?file=chorales/chor001.krn
The next complication would be first/second endings. And then cases such as da capo repeats (such as in minuet and trios).
Click to view example MEI data.
``` xmlTranscoded from Humdrum with Verovio version 0.9.12-dev-48e949d