Class MusicXmlIo
Imports MusicXML into the engine's NoteBuffer / NoteEvent model.
This pass handles the common core of score-partwise: pitched notes
(step/octave/alter), rests, chords (<chord/>), per-measure <divisions>,
multiple measures, multiple parts (merged into one time line), <backup>/
<forward> cursor moves, and tie merging (a <tie> chain becomes one
sustained note). Times are converted to the engine's whole-note units.
Multi-voice parts import correctly because voice timing rides on <backup>/
<forward>, and dynamics (<dynamics> marks and <sound dynamics>)
set note velocity (and single-voice export writes velocity back as <sound dynamics>).
Compressed .mxl archives are unwrapped and the score-timewise layout is transposed
to partwise on import; grace notes are approximated as short notes at the following beat.
Remaining boundaries: tuplet grouping metadata (<time-modification>) is ignored, though
tuplet durations import exactly; and an <unpitched> note (a hit on a
percussion staff) is not imported — it takes up its time and yields no note, since the engine
holds pitches and a drum has none. Export bars the timeline into measures of the
requested meter (4/4 unless one is given) and splits notes crossing a barline into tied
segments.
Pitches are sounding pitches. A transposing instrument's part is written at written
pitch and declares the difference in <attributes><transpose>
(<chromatic> semitones plus <octave-change> octaves); import adds that
offset to every note of the part from the point the element appears — per staff, when the
element carries a number — so a B♭ clarinet's written D5 imports as the C5 it sounds.
Export writes concert pitch and no <transpose>, since the buffer holds nothing else.
public static class MusicXmlIo
- Inheritance
-
MusicXmlIo
- Inherited Members
Remarks
Import used to ignore <transpose> and hand back the written pitch, so a clarinet
part arrived a whole tone sharp and a horn part a fifth sharp, and every analysis downstream —
key, chords, intervals against the other parts — read the wrong notes.
Methods
Export(NoteBuffer, Stream)
Writes a NoteBuffer as MusicXML (4/4) to a stream.
public static void Export(NoteBuffer buffer, Stream stream)
Parameters
bufferNoteBufferstreamStream
Exceptions
- ArgumentNullException
bufferorstreamis null.- ArgumentException
A note has a negative offset, which MusicXML cannot represent.
- InvalidOperationException
The offsets and durations use denominators whose least common multiple overflows the 64-bit
<divisions>value.
Export(NoteBuffer, Stream, TimeSignature)
Writes a NoteBuffer as MusicXML, barred into timeSignature, to a stream.
public static void Export(NoteBuffer buffer, Stream stream, TimeSignature timeSignature)
Parameters
bufferNoteBufferstreamStreamtimeSignatureTimeSignature
Exceptions
- ArgumentNullException
bufferorstreamis null.- ArgumentException
A note has a negative offset, which MusicXML cannot represent.
- InvalidOperationException
The offsets and durations use denominators whose least common multiple overflows the 64-bit
<divisions>value.
Export(NoteBuffer, string)
Writes a NoteBuffer as MusicXML (4/4) to path.
public static void Export(NoteBuffer buffer, string path)
Parameters
bufferNoteBufferpathstring
Exceptions
- ArgumentNullException
bufferorpathis null.- ArgumentException
A note has a negative offset, which MusicXML cannot represent.
- InvalidOperationException
The offsets and durations use denominators whose least common multiple overflows the 64-bit
<divisions>value.
Export(NoteBuffer, string, TimeSignature)
Writes a NoteBuffer as MusicXML, barred into timeSignature, to a file.
public static void Export(NoteBuffer buffer, string path, TimeSignature timeSignature)
Parameters
bufferNoteBufferpathstringtimeSignatureTimeSignature
Exceptions
- ArgumentNullException
bufferorpathis null.- ArgumentException
A note has a negative offset, which MusicXML cannot represent.
- InvalidOperationException
The offsets and durations use denominators whose least common multiple overflows the 64-bit
<divisions>value.
Import(Stream)
Reads and imports MusicXML from a stream. Plain XML and compressed .mxl (a ZIP whose
score is named by META-INF/container.xml) are both accepted, detected by content.
Notes come back at sounding pitch: a part's <transpose> is applied on the way in.
Unpitched (percussion) notes are not imported.
public static NoteBuffer Import(Stream stream)
Parameters
streamStream
Returns
Remarks
An <unpitched> note — a hit on a percussion staff — is not imported: the engine
holds pitches and a drum has none. It still takes up its time, so a pitched note after it
in the same part stays on its beat, and the pitched parts of a score with a drum staff
import as they would with that staff absent. Such a note used to be refused as
having neither <pitch> nor <rest>, and a score with a drum part
could not be imported at all.
Exceptions
- ArgumentNullException
streamis null.- InvalidDataException
The document is not valid, importable MusicXML.
Import(string)
Reads and imports a MusicXML file from path. Notes come back at sounding
pitch: a part's <transpose> is applied on the way in. Unpitched (percussion)
notes are not imported.
public static NoteBuffer Import(string path)
Parameters
pathstring
Returns
Remarks
An <unpitched> note — a hit on a percussion staff — is not imported: the engine
holds pitches and a drum has none. It still takes up its time, so a pitched note after it
in the same part stays on its beat, and the pitched parts of a score with a drum staff
import as they would with that staff absent. Such a note used to be refused as
having neither <pitch> nor <rest>, and a score with a drum part
could not be imported at all.
Exceptions
- ArgumentNullException
pathis null.- InvalidDataException
The document is not valid, importable MusicXML.
Parse(string)
Imports MusicXML held in a string. Notes come back at sounding pitch: a part's
<transpose> is applied on the way in. Unpitched (percussion) notes are not
imported.
public static NoteBuffer Parse(string xml)
Parameters
xmlstring
Returns
Remarks
An <unpitched> note — a hit on a percussion staff — is not imported: the engine
holds pitches and a drum has none. It still takes up its time, so a pitched note after it
in the same part stays on its beat, and the pitched parts of a score with a drum staff
import as they would with that staff absent. Such a note used to be refused as
having neither <pitch> nor <rest>, and a score with a drum part
could not be imported at all.
Exceptions
- ArgumentNullException
xmlis null.- InvalidDataException
The document is not valid, importable MusicXML.
ToXml(NoteBuffer)
Serializes a NoteBuffer to a score-partwise MusicXML string, barred into
4/4 measures.
public static string ToXml(NoteBuffer buffer)
Parameters
bufferNoteBuffer
Returns
Remarks
Notes at the same onset and duration are written as a chord; gaps become rests; overlapping
notes are split into separate voices (via <backup>). The timeline is divided into
measures of the given meter, notes crossing a barline are split and tied, and pitches are
spelled with sharps — so import → export → import round-trips.
Dynamics are deliberately exported for single-voice output only (a per-voice dynamic has no clean MusicXML representation in this writer), and a chord is written with its first note's velocity — chords are assumed dynamically uniform.
Exceptions
- ArgumentNullException
bufferis null.- ArgumentException
A note has a negative offset, which MusicXML cannot represent.
- InvalidOperationException
The offsets and durations use denominators whose least common multiple overflows the 64-bit
<divisions>value.
ToXml(NoteBuffer, TimeSignature)
Serializes a NoteBuffer to a score-partwise MusicXML string, barred into
4/4 measures.
public static string ToXml(NoteBuffer buffer, TimeSignature timeSignature)
Parameters
bufferNoteBufferThe notes to serialize.
timeSignatureTimeSignatureThe meter to bar the notes into.
Returns
Remarks
Notes at the same onset and duration are written as a chord; gaps become rests; overlapping
notes are split into separate voices (via <backup>). The timeline is divided into
measures of the given meter, notes crossing a barline are split and tied, and pitches are
spelled with sharps — so import → export → import round-trips.
Dynamics are deliberately exported for single-voice output only (a per-voice dynamic has no clean MusicXML representation in this writer), and a chord is written with its first note's velocity — chords are assumed dynamically uniform.
Exceptions
- ArgumentNullException
bufferis null.- ArgumentException
A note has a negative offset, which MusicXML cannot represent.
- InvalidOperationException
The offsets and durations use denominators whose least common multiple overflows the 64-bit
<divisions>value.- InvalidOperationException
The offsets and durations use denominators whose least common multiple overflows the 64-bit
<divisions>value.