Skip to main content

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}