Skip to main content

vst3_host/
lib.rs

1//! # vst3-host
2//!
3//! A safe, simple, and lightweight Rust library for hosting VST3 plugins with audio
4//! playback, MIDI, and advanced plugin compatibility features.
5//!
6//! The audio path is correctness-first, not yet lock-free/real-time-tuned — see the
7//! [audio processing](https://docs.rs/vst3-host) notes for the current model and limits.
8//!
9//! ## Quick Start (Simple API)
10//!
11//! ```no_run
12//! use vst3_host::simple;
13//! use vst3_host::midi::MidiChannel;
14//!
15//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
16//! // Load a plugin with sensible defaults
17//! let mut plugin = simple::load_plugin("/path/to/synth.vst3")?;
18//!
19//! // Start processing audio
20//! plugin.start_processing()?;
21//!
22//! // Send a MIDI note
23//! plugin.send_midi_note(60, 127, MidiChannel::Ch1)?;
24//! # Ok(())
25//! # }
26//! ```
27//!
28//! ## Advanced Usage (Full Control)
29//!
30//! ```no_run
31//! use vst3_host::prelude::*;
32//!
33//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
34//! // Create a host with custom settings
35//! let mut host = Vst3Host::builder()
36//!     .sample_rate(48000.0)
37//!     .block_size(256)
38//!     .with_process_isolation(true)  // Crash protection
39//!     .add_scan_path("./my-plugins")
40//!     .build()?;
41//!
42//! // Load and configure plugin
43//! let mut plugin = host.load_plugin("/path/to/plugin.vst3")?;
44//! plugin.start_processing()?;
45//!
46//! // Real-time parameter automation
47//! plugin.update_parameters(|update| {
48//!     update.set(1, 0.5).set(2, 0.8);
49//!     Ok(())
50//! })?;
51//! # Ok(())
52//! # }
53//! ```
54
55#![deny(missing_docs)]
56
57pub mod audio;
58pub mod error;
59pub mod host;
60pub mod midi;
61pub mod parameters;
62pub mod playback;
63pub mod plugin;
64pub mod realtime;
65pub mod simple;
66pub mod transport;
67pub mod window;
68
69pub mod discovery;
70
71#[cfg(feature = "egui-widgets")]
72pub mod embed;
73
74#[cfg(feature = "cpal-backend")]
75pub mod backends;
76
77pub mod process_isolation;
78
79#[cfg(feature = "midi-input")]
80pub mod midi_input;
81
82mod internal;
83
84pub use audio::{
85    read_wav, AudioBackend, AudioBuffers, AudioConfig, AudioLevels, AudioStream, BusArrangements,
86    BusDirection, ChannelLevel, InputSource, MediaType, PeakMeter, RmsWindow, SignalSource,
87    SpeakerArrangement,
88};
89pub use discovery::{
90    discover_plugins_safe, get_detailed_plugin_info, probe_plugin_info_isolated, BusInfo,
91    BusLayout, ClassInfo, DetailedPluginInfo, FactoryInfo, PluginReport, SafeDiscoveryReport,
92    SafeDiscoverySkip, DEFAULT_PROBE_TIMEOUT,
93};
94#[cfg(feature = "egui-widgets")]
95pub use embed::{EditorRect, EmbeddedEditor};
96pub use error::{Error, Result};
97pub use host::{DiscoveryProgress, ProbeResult, Vst3Host, Vst3HostBuilder};
98pub use midi::{cc, MidiChannel, MidiEvent, NoteExpressionInfo, NoteExpressionType, NoteId};
99#[cfg(feature = "midi-input")]
100pub use midi_input::{
101    bind_to_handle, connect, list_midi_input_ports, MidiInputConnection, MidiInputPort,
102};
103pub use parameters::{
104    AutomationCurve, AutomationPoint, Parameter, ParameterAutomation, ParameterChange,
105};
106pub use playback::{
107    play_realtime_with_backend, play_with_backend, play_with_input_backend, AudioHandle, MidiSink,
108    RtAudioHandle,
109};
110pub use plugin::{
111    OutputMidiConsumer, ParameterEdit, ParameterEditKind, Plugin, PluginInfo, PluginPreset,
112    PluginUnit, ProcessMode, WindowHandle,
113};
114pub use realtime::{RealtimePluginRunner, RtControl};
115pub use transport::{AutomationLane, BlockEvents, MidiClip, Timeline};
116pub use window::PluginWindow;
117
118/// Prelude module for convenient imports
119pub mod prelude {
120    pub use crate::{
121        audio::{
122            AudioBackend, AudioBuffers, AudioConfig, AudioLevels, AudioStream, BusArrangements,
123            BusDirection, ChannelLevel, InputSource, MediaType, PeakMeter, RmsWindow, SignalSource,
124            SpeakerArrangement,
125        },
126        // NOTE: `Result` is intentionally NOT re-exported here. A single-type-param
127        // `Result<T>` alias in a glob prelude shadows `std::result::Result` and breaks
128        // any `Result<T, E>` written by consumers. Use `vst3_host::Result` explicitly.
129        error::Error,
130        host::{DiscoveryProgress, Vst3Host, Vst3HostBuilder},
131        midi::{cc, MidiChannel, MidiEvent, NoteExpressionInfo, NoteExpressionType, NoteId},
132        parameters::{AutomationCurve, AutomationPoint, Parameter, ParameterAutomation},
133        playback::{play_with_backend, AudioHandle},
134        plugin::{ParameterEdit, ParameterEditKind, Plugin, PluginInfo, ProcessMode, WindowHandle},
135        transport::{AutomationLane, MidiClip, Timeline},
136        window::PluginWindow,
137    };
138
139    #[cfg(feature = "cpal-backend")]
140    pub use crate::backends::CpalBackend;
141
142    #[cfg(feature = "midi-input")]
143    pub use crate::midi_input::{MidiInputConnection, MidiInputPort};
144}
145
146#[cfg(test)]
147mod tests {
148    use super::*;
149
150    #[test]
151    fn test_host_creation() {
152        let host = Vst3Host::new();
153        assert!(host.is_ok());
154    }
155
156    #[test]
157    fn new_scans_default_paths_like_default() {
158        // new() and Vst3Host::default() must agree on scan_default_paths (both scan).
159        let via_new = Vst3Host::new().unwrap();
160        assert!(
161            via_new.scan_default_paths,
162            "Vst3Host::new() should scan standard system paths"
163        );
164        assert_eq!(
165            via_new.scan_default_paths,
166            Vst3Host::default().scan_default_paths
167        );
168    }
169
170    #[test]
171    fn test_host_builder() {
172        let host = Vst3Host::builder()
173            .sample_rate(48000.0)
174            .block_size(1024)
175            .build();
176        assert!(host.is_ok());
177
178        let host = host.unwrap();
179        assert_eq!(host.config().sample_rate, 48000.0);
180        assert_eq!(host.config().block_size, 1024);
181    }
182}