bevy_midix 4.0.0-alpha.8

The MIDI plugin for humans. Out-of-the-box soundfont synthesizer, commands, and input!
Documentation
use bevy::prelude::*;
use midix::prelude::*;

use crate::assets::SoundFontAsset;

/// Component that specifies which soundfont to use for a MIDI synth
#[derive(Component)]
pub struct SynthPlayer {
    pub(crate) handle: Handle<SoundFontAsset>,
    pub(crate) midi_input_enabled: bool,
}

impl SynthPlayer {
    /// Creates a new SynthPlayer with the given soundfont and MIDI input configuration.
    ///
    /// The soundfont handle will be used to load instrument samples, while the
    /// `midi_input_enabled` flag determines whether this player responds to incoming
    /// MIDI events from connected devices. See [`MidiInput`](crate::input::MidiInput) for more info.
    pub fn new(handle: Handle<SoundFontAsset>, midi_input_enabled: bool) -> Self {
        Self {
            handle,
            midi_input_enabled,
        }
    }

    /// Gets a reference to the soundfont asset handle used by this player.
    pub fn handle(&self) -> &Handle<SoundFontAsset> {
        &self.handle
    }
}

/// Component for sending MIDI commands to a synthesizer node via ECS.
///
/// This is automatically added to any [`MidiSynthNode`](crate::prelude::MidiSynthNode) or [`SynthPlayer`].
#[derive(Component, Default)]
pub struct SynthCommands {
    /// Queue of MIDI commands to send
    pub queue: Vec<ChannelVoiceMessage>,
}

impl SynthCommands {
    /// Add a MIDI command to the queue
    pub fn send(&mut self, command: ChannelVoiceMessage) {
        self.queue.push(command);
    }

    /// Add multiple MIDI commands to the queue
    pub fn send_batch(&mut self, commands: impl IntoIterator<Item = ChannelVoiceMessage>) {
        self.queue.extend(commands);
    }

    /// Take all commands, leaving the queue empty
    pub fn take(&mut self) -> Vec<ChannelVoiceMessage> {
        std::mem::take(&mut self.queue)
    }
}