Skip to main content

to_musicxml

Function to_musicxml 

Source
pub fn to_musicxml(score: &Stream, options: &ExportOptions) -> Result<String>
Available on crate feature musicxml only.
Expand description

Writes a score as a MusicXML document.

use music21_rs::{Duration, Note, Stream, StreamKind, TimeSignature};
use music21_rs::musicxml::{ExportOptions, to_musicxml};

let mut measure = Stream::with_kind(StreamKind::Measure);
measure.set_number(1);
measure.insert(0.0, TimeSignature::new(1, 4)?);
measure.push(Note::from_name("D#4")?.with_duration(Duration::quarter()));
let mut part = Stream::with_kind(StreamKind::Part);
part.push(measure);
let mut score = Stream::with_kind(StreamKind::Score);
score.push(part);

let xml = to_musicxml(&score, &ExportOptions::default())?;
assert!(xml.contains("<step>D</step>"));
assert!(xml.contains("<alter>1</alter>"));
assert!(xml.contains("<duration>10080</duration>"));

With ExportOptions::make_notation a part or a stream of loose notes may be handed in as readily as a score:

use music21_rs::{Duration, Note, Stream, StreamKind, TimeSignature};
use music21_rs::musicxml::{ExportOptions, to_musicxml};

let mut part = Stream::with_kind(StreamKind::Part);
part.insert(0.0, TimeSignature::new(3, 4)?);
part.insert(0.0, Note::from_name("C4")?.with_duration(Duration::new(5.0)?));
let options = ExportOptions {
    make_notation: true,
    ..ExportOptions::default()
};
let xml = to_musicxml(&part, &options)?;
// A dotted half tied to a half, in two measures.
assert_eq!(xml.matches("<measure ").count(), 2);
assert!(xml.contains("<tie type=\"start\" />"));

§Errors

A part with no measures, a score nested in a score, a duration no single note value writes, and anything the crate cannot yet write: each as music21’s MusicXMLExportException says it where music21 raises. Making the notation first leaves only what no notation can write: a length no tie of note values reaches that is not an unprinted rest.