sim_lib_midi_core/lib.rs
1//! Core MIDI data model and in-memory I/O for the SIM music stack.
2//!
3//! This crate defines the protocol-agnostic MIDI types shared across the
4//! constellation: tick-based timing ([`TickTime`]), the bounded integer
5//! domains used by MIDI bytes ([`U7`], [`U14`], [`Channel`]), the event model
6//! ([`MidiEvent`], [`MidiPayload`], [`ChannelMessage`], [`MetaEvent`],
7//! [`SysExEvent`]), and the streaming [`MidiSource`]/[`MidiSink`] traits with
8//! in-memory implementations. It also provides the [`NoteEchoPlayer`]
9//! transform, controller-number constants, tempo conversions, and the
10//! host-registered [`MidiIoLib`] that exposes the in-memory cards to a running
11//! SIM [`Cx`](sim_kernel::Cx).
12//!
13//! Higher layers (Standard MIDI File, SysEx, live transports) build on this
14//! model rather than redefining it.
15//!
16//! # Examples
17//!
18//! ```
19//! use sim_lib_midi_core::{Channel, ChannelMessage, U7};
20//!
21//! let note = ChannelMessage::NoteOn {
22//! ch: Channel::new(0).unwrap(),
23//! key: U7(60),
24//! vel: U7(100),
25//! };
26//! assert!(matches!(note, ChannelMessage::NoteOn { .. }));
27//! ```
28//!
29//! ```
30//! use sim_lib_midi_core::TickTime;
31//!
32//! // 480 ticks at 480 tpq is exactly one quarter note.
33//! let one_quarter = TickTime::new(480, 480).unwrap();
34//! assert_eq!(one_quarter.as_f64_quarters(), 1.0);
35//! // Rebasing to a coarser resolution is exact here.
36//! assert_eq!(one_quarter.rebase(96).unwrap().ticks, 96);
37//! ```
38
39#![forbid(unsafe_code)]
40#![allow(deprecated)]
41#![deny(missing_docs)]
42
43mod cc;
44mod error;
45mod io;
46mod model;
47mod player;
48mod runtime;
49mod tempo;
50
51pub mod meta_view;
52pub mod wire;
53
54pub use cc::*;
55pub use error::*;
56pub use io::*;
57pub use model::*;
58pub use player::*;
59pub use runtime::*;
60pub use tempo::*;
61
62#[cfg(test)]
63mod tests;