nannou_midi 0.20.0

The MIDI API for nannou - the creative-coding framework.
Documentation
use bevy::prelude::*;

#[derive(Component, Clone, Debug, Reflect)]
pub struct MidiPort {
    pub direction: MidiPortDirection,
}

#[derive(Clone, Debug, PartialEq, Eq, Reflect)]
pub enum MidiPortDirection {
    Input,
    Output,
}

#[derive(Component, Clone, Debug, Default, Reflect)]
pub struct MidiInput {
    pub port: Option<Entity>,
}

#[derive(Component, Clone, Debug, Default, Reflect)]
pub struct MidiOutput {
    pub port: Option<Entity>,
}

#[derive(Component)]
pub struct MidiInputStream {
    pub(crate) messages: Vec<MidiData>,
}

impl MidiInputStream {
    pub(crate) fn new() -> Self {
        Self {
            messages: Vec::new(),
        }
    }

    pub fn read(&mut self) -> impl Iterator<Item = MidiData> + '_ {
        self.messages.drain(..)
    }
}

#[derive(Component)]
pub struct MidiOutputStream {
    pub(crate) outbox: Vec<MidiMessage>,
}

impl MidiOutputStream {
    pub(crate) fn new() -> Self {
        Self { outbox: Vec::new() }
    }

    pub fn send(&mut self, msg: MidiMessage) {
        self.outbox.push(msg);
    }
}

#[derive(Component, Clone, Debug, Reflect)]
pub struct MidiError {
    pub message: String,
}

const NOTE_ON_STATUS: u8 = 0b1001_0000;
const NOTE_OFF_STATUS: u8 = 0b1000_0000;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct MidiMessage {
    pub msg: [u8; 3],
}

impl From<[u8; 3]> for MidiMessage {
    fn from(msg: [u8; 3]) -> Self {
        MidiMessage { msg }
    }
}

impl MidiMessage {
    #[must_use]
    pub fn is_note_on(&self) -> bool {
        (self.msg[0] & 0xF0) == NOTE_ON_STATUS && self.msg[2] != 0
    }

    #[must_use]
    pub fn is_note_off(&self) -> bool {
        (self.msg[0] & 0xF0) == NOTE_OFF_STATUS
            || ((self.msg[0] & 0xF0) == NOTE_ON_STATUS && self.msg[2] == 0)
    }

    #[must_use]
    pub fn channel(&self) -> u8 {
        self.msg[0] & 0x0F
    }
}

#[derive(Clone, Debug)]
pub struct MidiData {
    pub stamp: u64,
    pub message: MidiMessage,
}