music21 version: 9.1.0 (also verified against the current MEI dispatch table)
Problem summary: music21.mei.base has no handler for <bTrem> (absent from the layer dispatch table), and an unhandled element's children are not imported. The result is not a cosmetic loss: the tremolo's note/chord contributes zero duration, so every onset after it in that voice shifts earlier by the tremolo's duration.
In the piece where I hit this (a Humdrum score rendered to MEI by verovio, which correctly emits <bTrem unitdur="8"> for a beamed tremolo), one dropped chord shifted the entire remainder of the piece by a quarter note — 169 spurious / 171 missing onsets out of ~1,900 when compared event-wise against the source.
Minimal repro (self-contained, 4/4 bar with notes on beats 1, 2, 3):
import music21
mei = '''<?xml version="1.0" encoding="UTF-8"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.1">
<music><body><mdiv><score>
<scoreDef meter.count="4" meter.unit="4">
<staffGrp><staffDef n="1" lines="5" clef.shape="G" clef.line="2"/></staffGrp>
</scoreDef>
<section>
<measure n="1">
<staff n="1">
<layer n="1">
<note xml:id="n1" dur="4" oct="4" pname="c"/>
<bTrem xml:id="bt1" form="meas" unitdur="8">
<chord xml:id="ch1" dur="4">
<note xml:id="n2" oct="4" pname="e"/>
<note xml:id="n3" oct="5" pname="e"/>
</chord>
</bTrem>
<note xml:id="n4" dur="2" oct="4" pname="g"/>
</layer>
</staff>
</measure>
</section>
</score></mdiv></body></music>
</mei>'''
s = music21.converter.parse(mei, format="mei")
for n in s.flatten().notes:
print(n.offset, [p.nameWithOctave for p in n.pitches], n.duration.quarterLength)
Actual output:
0.0 ['C4'] 1.0
1.0 ['G4'] 2.0
The <bTrem> chord (E4+E5 on beat 2) is gone, and G4 lands on beat 2 instead of beat 3.
Expected: the chord imported with its notated duration (offset 1.0, quarterLength 1.0) and G4 at offset 2.0 — ideally with a Tremolo expression attached, but timing correctness is the important part.
Suggested minimal fix short of full tremolo support: treat <bTrem> (and <fTrem>) transparently in the layer dispatch — import child <note>/<chord> elements as ordinary notes so durations survive, optionally attaching a Tremolo/TremoloSpanner expression when unitdur/@measperf is present. Silent deletion is the one behaviour that corrupts everything downstream of the tremolo.
music21 version: 9.1.0 (also verified against the current MEI dispatch table)
Problem summary:
music21.mei.basehas no handler for<bTrem>(absent from the layer dispatch table), and an unhandled element's children are not imported. The result is not a cosmetic loss: the tremolo's note/chord contributes zero duration, so every onset after it in that voice shifts earlier by the tremolo's duration.In the piece where I hit this (a Humdrum score rendered to MEI by verovio, which correctly emits
<bTrem unitdur="8">for a beamed tremolo), one dropped chord shifted the entire remainder of the piece by a quarter note — 169 spurious / 171 missing onsets out of ~1,900 when compared event-wise against the source.Minimal repro (self-contained, 4/4 bar with notes on beats 1, 2, 3):
Actual output:
The
<bTrem>chord (E4+E5 on beat 2) is gone, and G4 lands on beat 2 instead of beat 3.Expected: the chord imported with its notated duration (offset 1.0, quarterLength 1.0) and G4 at offset 2.0 — ideally with a
Tremoloexpression attached, but timing correctness is the important part.Suggested minimal fix short of full tremolo support: treat
<bTrem>(and<fTrem>) transparently in the layer dispatch — import child<note>/<chord>elements as ordinary notes so durations survive, optionally attaching aTremolo/TremoloSpannerexpression whenunitdur/@measperfis present. Silent deletion is the one behaviour that corrupts everything downstream of the tremolo.