midi_controller/routing.rs
1//! MIDI routing types: port bitmask and tagged output messages.
2//!
3//! The controller uses these to express routing decisions.
4//! Firmware maps port bits to physical hardware (UART, USB, BLE).
5
6use bitflags::bitflags;
7
8bitflags! {
9 /// Bitmask of MIDI ports. Extensible — new ports are new bits.
10 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
11 pub struct MidiPort: u8 {
12 /// DIN 5-pin MIDI (UART)
13 const DIN = 0x01;
14 /// USB MIDI
15 const USB = 0x02;
16 /// Bluetooth LE MIDI (future)
17 const BLE = 0x04;
18 }
19}
20
21impl MidiPort {
22 /// All currently defined ports.
23 pub const ALL: Self = Self::DIN.union(Self::USB);
24}
25
26/// A MIDI message tagged with destination port(s).
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct MidiOut {
29 /// Raw MIDI bytes (fits MIDI 1.0 and future MIDI 2.0 UMP).
30 pub data: [u8; 8],
31 /// Number of valid bytes in `data`.
32 pub len: u8,
33 /// Destination ports (bitmask).
34 pub dest: MidiPort,
35}
36
37impl MidiOut {
38 /// Create a MIDI 1.0 channel message (up to 3 bytes) for the given destination(s).
39 pub fn new(data: &[u8], dest: MidiPort) -> Self {
40 let mut buf = [0u8; 8];
41 let len = data.len().min(8);
42 buf[..len].copy_from_slice(&data[..len]);
43 Self {
44 data: buf,
45 len: len as u8,
46 dest,
47 }
48 }
49
50 /// The message bytes.
51 pub fn bytes(&self) -> &[u8] {
52 &self.data[..self.len as usize]
53 }
54}