1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
//! This is a stand-alone MIDI host with helpers for doing real-time handling of MIDI messages in //! the audio-thread and to integrate with VST plugins. //! //! This is part of https://github.com/yamadapc/augmented-audio. //! //! ## Usage //! To use this crate: //! //! * [`basedrop::Collector`] You'll need to set-up `basedrop` or `audio-garbage-collector` //! * [`host::MidiHost`] should be created //! - This will connect to inputs & push messages to a queue //! * [`audio_thread::MidiAudioThreadHandler`] On your audio thread you should pop from the queue //! - This is enough to add MIDI to a standalone [`audio_processor_traits::MidiEventHandler`] //! * [`vst::MidiVSTConverter`] If you're implementing a host, you'll have to convert messages onto //! the VST API //! //! ``` //! use audio_processor_standalone_midi::audio_thread::MidiAudioThreadHandler; //! use audio_processor_standalone_midi::host::MidiHost; //! use audio_processor_standalone_midi::vst::MidiVSTConverter; //! use basedrop::Collector; //! //! fn main() { //! // GC ====================================================================================== //! // See `audio-garbage-collector` for an easier to use wrapper on top of this. //! // //! // `Collector` will let us use reference counted values on the audio-thread, which will be //! // pushed to a queue for de-allocation. You must set-up a background thread that forces it //! // to actually collect garbage from the queue. //! let gc = Collector::new(); //! let handle = gc.handle(); //! //! // Host ==================================================================================== //! // A host may be created with `new` or `default_with_handle`. //! let mut host = MidiHost::default_with_handle(&handle); //! // It'll connect to all MIDI input ports when started //! host.start().expect("Failed to connect"); //! // The host will push messages onto a lock-free queue. This is a reference counted value. //! let midi_messages_queue = host.messages().clone(); //! //! // Audio-thread ============================================================================ //! // ... //! // Within your audio-thread //! // ... //! // You'll want to share a `MidiAudioThreadHandler` between process calls as it pre-allocates //! // buffers. //! let mut midi_audio_thread_handler = MidiAudioThreadHandler::default(); //! //! // On each tick you'll call collect //! midi_audio_thread_handler.collect_midi_messages(&midi_messages_queue); //! // You'll get the MIDI message buffer //! let midi_messages = midi_audio_thread_handler.buffer(); //! // ^ This is a `&Vec<MidiMessageEntry>`. If you're using `audio-processor-traits`, you can //! // pass this into any `MidiEventHandler` implementor. //! //! // VST interop ============================================================================= //! // If you want to interface with a VST plugin, you'll need to convert messages into the //! // C-api. //! // ... //! // You'll want to share this between process calls as it pre-allocates buffers. //! let mut midi_vst_converter = MidiVSTConverter::default(); //! midi_vst_converter.accept(&midi_messages); //! // This can be passed into VST plugins. //! let events: &vst::api::Events = midi_vst_converter.events(); //! } //! ``` /// Audio-thread handling of messages pub mod audio_thread; /// Defaults pub mod constants; /// Hosting of MIDI pub mod host; /// VST API conversion pub mod vst;