-
Notifications
You must be signed in to change notification settings - Fork 0
Quick Start
Rodrigo Agurto edited this page May 30, 2026
·
2 revisions
use verovio::Toolkit;
let mut tk = Toolkit::new();
tk.load_data(
"@start:demo\n@clef:G-2\n@keysig:xF\n@key:\n@timesig:\n@data:'4G/4-\n@end:demo\n",
)?;
for page in 1..=tk.page_count() {
let svg = tk.render_to_svg(page)?;
std::fs::write(format!("page-{page}.svg"), svg)?;
}
# Ok::<(), verovio::Error>(())Verovio auto-detects MEI, MusicXML, ABC, and PAE from content:
let mei = std::fs::read_to_string("score.mei")?;
let mut tk = verovio::Toolkit::from_data(&mei)?;// from_file / load_file delegate to Verovio's upstream loader, so
// UTF-16 MusicXML and compressed .mxl archives work transparently.
let mut tk = verovio::Toolkit::from_file("score.musicxml")?;// .mxl bytes in memory (e.g. downloaded from a URL):
let mxl_bytes = std::fs::read("score.mxl")?;
let mut tk = verovio::Toolkit::new();
tk.load_zip_data_buffer(&mxl_bytes)?;Force a specific input format when auto-detect is ambiguous (rare, but happens with bare PAE):
tk.set_input_from("pae")?;
tk.load_data("@clef:G-2\n@keysig:\n@timesig:4/4\n@data:'4C")?;| Output | Method | Feature |
|---|---|---|
| SVG (per page) | tk.render_to_svg(page) |
|
| SVG (writer) | tk.render_to_svg_writer(page, &mut w) |
|
| SVG (measure-range) | tk.render_svg_measure_range(from, to, "\n") |
|
| PNG | tk.render_to_png(page, scale) |
png |
| PNG (all pages) | tk.render_to_png_all_pages(scale) |
png |
| PDF (per page) | tk.render_to_pdf(page) |
pdf |
| PDF (multi-page) | tk.render_to_pdf_all_pages() |
pdf |
| MIDI (SMF bytes) | tk.render_to_midi_bytes() |
|
| MIDI + policy | tk.render_to_midi_bytes_with_policy(&policy) |
|
| MIDI (writer) | tk.render_to_midi_writer(&mut w) |
|
| WAV (offline) | tk.render_to_wav(&sf2_bytes, sample_rate) |
audio |
| Timemap (typed) |
tk.timemap() → Vec<TimemapEvent>
|
|
| MEI export |
tk.to_mei() / tk.to_mei_with_options(&MeiOptions)
|
|
| PAE export | tk.render_to_pae() |
Loading any supported format and exporting to MEI gives you the canonical "save as MEI" pipeline. MusicXML → MEI, ABC → MEI, PAE → MEI all work the same way:
let mut tk = verovio::Toolkit::from_file("score.musicxml")?;
let mei = tk.to_mei()?; // score-based, all pages, IDs preserved
std::fs::write("score.mei", mei)?;For MEI-Basic output or page-scoped export, use the typed options:
use verovio::MeiOptions;
let basic = tk.to_mei_with_options(&MeiOptions {
basic: true, // MEI-Basic subset
remove_ids: true, // strip Verovio-added @xml:id attributes
..Default::default() // score_based: true (matches upstream)
})?;let md = tk.metadata()?; // title / composer / instruments
let measures = tk.measures()?; // (id, start_ms, end_ms, qfrac)
let bboxes = tk.bbox_map()?; // id -> pixel rect for hit testing
let tempo = tk.tempo_map()?; // TempoChange list with qstamp↔ms
let timemap = tk.timemap()?; // playback sync source of truthSee Score Reading for the full query surface.
use verovio::lookup::{sounding_at, PlaybackCursor};
let timemap = tk.timemap()?; // one FFI + JSON parse
let mut cursor = PlaybackCursor::new(&timemap);
for tick_ms in playback_clock() {
let active = cursor.advance_to(tick_ms);
// …update UI / driver from `active` (sorted ids)
}
# Ok::<(), verovio::Error>(())See Score Reading for LoopCursor, chord_at,
note_duration, events_in_range, etc.
Every allocating method has an _into variant that writes into a
caller-owned buffer:
let mut svg_buf = String::new();
for page in 1..=tk.page_count() {
tk.render_to_svg_into(page, &mut svg_buf)?;
std::fs::write(format!("page-{page}.svg"), &svg_buf)?;
}The C++ side still allocates a std::string per render (Verovio has no
streaming overload upstream), but the Rust-side String reuses its
capacity.