oxisound-midi — MIDI device I/O for OxiSound
oxisound-midi implements the MidiDevice, MidiInput, and MidiOutput traits from oxisound-core on top of the midir crate. It enumerates MIDI ports, opens input/output connections, and (on supported platforms) creates virtual MIDI ports. Platform selection is automatic: CoreMIDI on macOS/iOS, WinMM/WinRT on Windows, and the ALSA sequencer on Linux.
Pure-Rust status: platform backend (NOT Pure Rust).
midirbinds the host OS's native MIDI subsystem through C-FFI: the ALSA sequencer +libcon Linux, CoreMIDI (coremidi) on macOS/iOS, and the WinRT path of thewindowscrate on Windows. These are auto-selected bycfg(target_os)and cannot be turned off — MIDI hardware access has no pure-Rust equivalent. Under the COOLJAPAN Pure Rust Policy this is a permitted OS-boundary backend, analogous to the CPAL and JACK audio backends. (Note:midir's own optionaljack/jack-sysfeature is not enabled here, so libjack is never linked through this crate.) The crate's own code is#![forbid(unsafe_code)].
Installation
[]
= "0.1.2"
This crate has no Cargo features; the platform MIDI backend is selected automatically at compile time.
Quick Start
List MIDI ports and send a Note On to the first output port:
use ;
use MidiDeviceImpl;
// Enumerate every MIDI device (input + output).
for d in enumerate_midi?
// Open output port 0 and play middle C.
let mut out = open_midi_output?;
out.send?;
# Ok::
Poll an input port for incoming messages:
use ;
use MidiDeviceImpl;
let mut input = open_midi_input?;
while let Some = input.receive?
# Ok::
API Overview
MidiDeviceImpl
A zero-sized type implementing oxisound_core::MidiDevice. Each call creates a fresh midir client internally; for repeated port queries prefer MidiHost, which amortises client creation.
| Method | Description |
|---|---|
enumerate_midi() |
List all MIDI devices as Vec<MidiDeviceInfo>. Input/output ports sharing a name are merged into a single in+out entry. Returns Ok([]) on headless systems rather than failing |
open_midi_input(port) |
Open input port by index → Box<dyn MidiInput>; out-of-range index → Device error |
open_midi_output(port) |
Open output port by index → Box<dyn MidiOutput>; out-of-range index → Device error |
The returned MidiInput is non-blocking: receive() returns Ok(None) when no message is queued and Err(Disconnected) once the callback channel closes. The returned MidiOutput serialises each MidiMessage via MidiMessage::to_bytes() (adding F0/F7 framing for SysEx).
MidiHost
Holds midir input and output clients for its lifetime, reducing per-call initialization overhead. Construct with MidiHost::new().
| Method | Description |
|---|---|
new() |
Initialize input + output clients; Err(Device) only if both are unavailable |
default() |
Infallible constructor (empty host on failure) |
input_port_names() |
All MIDI input port names (empty Vec if none) |
output_port_names() |
All MIDI output port names (empty Vec if none) |
create_virtual_input(name, FnMut(MidiMessage)) |
Create a virtual input port (macOS / Linux); returns Unsupported on Windows |
create_virtual_output(name) |
Create a virtual output port (macOS / Linux); returns Unsupported on Windows |
Virtual ports are supported on macOS (CoreMIDI) and Linux (ALSA sequencer); WinMM does not support them, so both virtual-port methods return OxiSoundError::Unsupported on Windows.
MIDI types (from oxisound-core)
These are re-used from oxisound-core, not redefined here:
MidiDeviceInfo { name, is_input, is_output, port_count }MidiMessage { status, data, timestamp_micros }— withis_sysex(),sysex_payload(),new_sysex(),to_bytes()MidiInput::receive(),MidiOutput::send(),MidiDevice(the traitMidiDeviceImplimplements)
SysEx framing is handled transparently: inbound raw bytes are parsed so that a 0xF0 … 0xF7 stream becomes a MidiMessage carrying only the payload (no framing bytes), and to_bytes() re-adds the framing on send.
Errors
All fallible methods return oxisound_core::OxiSoundError. Notable mappings: an out-of-range or unopenable port → Device; a dropped input callback channel → Disconnected; virtual ports on Windows → Unsupported. See the oxisound-core error table.
Cross-references
- Traits & types:
oxisound-core—MidiDevice,MidiInput,MidiOutput,MidiMessage,MidiDeviceInfo,MidiClock. - JACK MIDI:
oxisound-jackexposesJackMidiInput/JackMidiOutputfor low-latency MIDI over the JACK transport. - Facade:
oxisound. Sibling crateoxisound-smfhandles Standard MIDI File parsing.
License
Apache-2.0 — COOLJAPAN OU (Team Kitasan)