| Crates.io | mkmidilibrary |
| lib.rs | mkmidilibrary |
| version | 0.1.2 |
| created_at | 2025-12-17 06:10:24.092915+00 |
| updated_at | 2025-12-17 07:48:39.608235+00 |
| description | Music scoring and MIDI library for Rust |
| homepage | |
| repository | https://github.com/mkaudio-company/mkmidilibrary |
| max_upload_size | |
| id | 1989352 |
| size | 413,634 |
A comprehensive Rust library for music notation, MIDI file I/O, and real-time MIDI communication.
mkmidilibrary is a Rust translation and unification of three popular music libraries:
Add to your Cargo.toml:
[dependencies]
mkmidilibrary = "0.1.2"
realtime - Real-time MIDI I/O (enabled by default)graphics - Score rendering with mkgraphic (enabled by default)To disable optional features:
[dependencies]
mkmidilibrary = { version = "0.1.2", default-features = false }
use mkmidilibrary::prelude::*;
// Create a pitch (Middle C)
let pitch = Pitch::new(Step::C, 4);
// Create notes with different durations
let quarter_note = Note::quarter(pitch);
let half_note = Note::half(pitch);
let dotted_quarter = Note::dotted_quarter(pitch);
// Create a C major chord
let c_major = Chord::major_triad(Pitch::new(Step::C, 4));
use mkmidilibrary::prelude::*;
// Create a new score
let mut score = Score::new();
score.set_title("My Composition");
// Create a part
let mut part = Part::with_name("Piano");
// Create a measure with time signature
let mut measure = Measure::new(1);
measure.set_time_signature(TimeSignature::new(4, 4));
// Add notes
measure.append(MusicElement::Note(Note::quarter(Pitch::new(Step::C, 4))));
measure.append(MusicElement::Note(Note::quarter(Pitch::new(Step::E, 4))));
measure.append(MusicElement::Note(Note::quarter(Pitch::new(Step::G, 4))));
measure.append(MusicElement::Note(Note::quarter(Pitch::new(Step::C, 5))));
part.add_measure(measure);
score.add_part(part);
use mkmidilibrary::midi::{MidiFile, MidiMessage};
// Read a MIDI file
let midi = MidiFile::read("song.mid")?;
println!("Tracks: {}", midi.num_tracks());
println!("Ticks per quarter: {}", midi.ticks_per_quarter());
// Create a new MIDI file
let mut midi = MidiFile::new();
midi.set_ticks_per_quarter(480);
let track = midi.add_track();
track.add_note(0, 480, 0, 60, 100); // C4 quarter note
track.add_note(480, 480, 0, 64, 100); // E4 quarter note
midi.write("output.mid")?;
use mkmidilibrary::realtime::{MidiInput, MidiOutput};
// List available ports
let input = MidiInput::new("My App")?;
for port in input.ports() {
println!("Input: {}", port.name());
}
let mut output = MidiOutput::new("My App")?;
for port in output.ports() {
println!("Output: {}", port.name());
}
// Open a port and send a note
output.open_port(0, "Out")?;
output.send_message(&[0x90, 60, 100])?; // Note On
output.send_message(&[0x80, 60, 0])?; // Note Off
use mkmidilibrary::render::{ScoreRenderer, RenderConfig, render_score_to_image};
// Create a renderer
let renderer = ScoreRenderer::new();
// Render to PNG
let config = RenderConfig::default();
if let Some(png_data) = render_score_to_image(&score, &config) {
std::fs::write("score.png", png_data)?;
}
mkmidilibrary/
├── core/ # Music primitives (Pitch, Duration, Note, etc.)
├── stream/ # Container hierarchy (Score, Part, Measure, Voice)
├── midi/ # MIDI file I/O and translation
├── realtime/ # Real-time MIDI I/O (platform-specific)
├── notation/ # Musical notation elements
├── render/ # Graphical rendering (requires "graphics" feature)
└── analysis/ # Music analysis tools
| Platform | Real-time MIDI Backend |
|---|---|
| macOS | CoreMIDI |
| Linux | ALSA |
| Windows | Windows MM |
MIT License
Contributions are welcome! Please feel free to submit issues and pull requests.