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 window;
67
68pub mod discovery;
69
70#[cfg(feature = "egui-widgets")]
71pub mod embed;
72
73#[cfg(feature = "cpal-backend")]
74pub mod backends;
75
76pub mod process_isolation;
77
78mod internal;
79
80pub use audio::{
81    read_wav, AudioBackend, AudioBuffers, AudioConfig, AudioLevels, AudioStream, BusArrangements,
82    ChannelLevel, InputSource, PeakMeter, RmsWindow, SignalSource, SpeakerArrangement,
83};
84pub use discovery::{
85    discover_plugins_safe, get_detailed_plugin_info, probe_plugin_info_isolated, BusInfo,
86    BusLayout, ClassInfo, DetailedPluginInfo, FactoryInfo, PluginReport, SafeDiscoveryReport,
87    SafeDiscoverySkip, DEFAULT_PROBE_TIMEOUT,
88};
89#[cfg(feature = "egui-widgets")]
90pub use embed::{EditorRect, EmbeddedEditor};
91pub use error::{Error, Result};
92pub use host::{DiscoveryProgress, ProbeResult, Vst3Host, Vst3HostBuilder};
93pub use midi::{cc, MidiChannel, MidiEvent, NoteExpressionInfo, NoteExpressionType, NoteId};
94pub use parameters::{Parameter, ParameterAutomation, ParameterChange};
95pub use playback::{
96    play_realtime_with_backend, play_with_backend, play_with_input_backend, AudioHandle,
97    RtAudioHandle,
98};
99pub use plugin::{Plugin, PluginInfo, PluginPreset, PluginUnit, ProcessMode, WindowHandle};
100pub use realtime::{RealtimePluginRunner, RtControl};
101pub use window::PluginWindow;
102
103/// Prelude module for convenient imports
104pub mod prelude {
105    pub use crate::{
106        audio::{
107            AudioBackend, AudioBuffers, AudioConfig, AudioLevels, AudioStream, BusArrangements,
108            ChannelLevel, InputSource, PeakMeter, RmsWindow, SignalSource, SpeakerArrangement,
109        },
110        // NOTE: `Result` is intentionally NOT re-exported here. A single-type-param
111        // `Result<T>` alias in a glob prelude shadows `std::result::Result` and breaks
112        // any `Result<T, E>` written by consumers. Use `vst3_host::Result` explicitly.
113        error::Error,
114        host::{DiscoveryProgress, Vst3Host, Vst3HostBuilder},
115        midi::{cc, MidiChannel, MidiEvent, NoteExpressionInfo, NoteExpressionType, NoteId},
116        parameters::{Parameter, ParameterAutomation},
117        playback::{play_with_backend, AudioHandle},
118        plugin::{Plugin, PluginInfo, ProcessMode, WindowHandle},
119        window::PluginWindow,
120    };
121
122    #[cfg(feature = "cpal-backend")]
123    pub use crate::backends::CpalBackend;
124}
125
126#[cfg(test)]
127mod tests {
128    use super::*;
129
130    #[test]
131    fn test_host_creation() {
132        let host = Vst3Host::new();
133        assert!(host.is_ok());
134    }
135
136    #[test]
137    fn new_scans_default_paths_like_default() {
138        // new() and Vst3Host::default() must agree on scan_default_paths (both scan).
139        let via_new = Vst3Host::new().unwrap();
140        assert!(
141            via_new.scan_default_paths,
142            "Vst3Host::new() should scan standard system paths"
143        );
144        assert_eq!(
145            via_new.scan_default_paths,
146            Vst3Host::default().scan_default_paths
147        );
148    }
149
150    #[test]
151    fn test_host_builder() {
152        let host = Vst3Host::builder()
153            .sample_rate(48000.0)
154            .block_size(1024)
155            .build();
156        assert!(host.is_ok());
157
158        let host = host.unwrap();
159        assert_eq!(host.config().sample_rate, 48000.0);
160        assert_eq!(host.config().block_size, 1024);
161    }
162}