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    get_detailed_plugin_info, BusInfo, BusLayout, ClassInfo, DetailedPluginInfo, FactoryInfo,
86    PluginReport,
87};
88#[cfg(feature = "egui-widgets")]
89pub use embed::{EditorRect, EmbeddedEditor};
90pub use error::{Error, Result};
91pub use host::{DiscoveryProgress, ProbeResult, Vst3Host, Vst3HostBuilder};
92pub use midi::{cc, MidiChannel, MidiEvent};
93pub use parameters::{Parameter, ParameterAutomation, ParameterChange};
94pub use playback::{
95    play_realtime_with_backend, play_with_backend, play_with_input_backend, AudioHandle,
96    RtAudioHandle,
97};
98pub use plugin::{Plugin, PluginInfo, PluginPreset, PluginUnit, ProcessMode, WindowHandle};
99pub use realtime::{RealtimePluginRunner, RtControl};
100pub use window::PluginWindow;
101
102/// Prelude module for convenient imports
103pub mod prelude {
104    pub use crate::{
105        audio::{
106            AudioBackend, AudioBuffers, AudioConfig, AudioLevels, AudioStream, BusArrangements,
107            ChannelLevel, InputSource, PeakMeter, RmsWindow, SignalSource, SpeakerArrangement,
108        },
109        // NOTE: `Result` is intentionally NOT re-exported here. A single-type-param
110        // `Result<T>` alias in a glob prelude shadows `std::result::Result` and breaks
111        // any `Result<T, E>` written by consumers. Use `vst3_host::Result` explicitly.
112        error::Error,
113        host::{DiscoveryProgress, Vst3Host, Vst3HostBuilder},
114        midi::{cc, MidiChannel, MidiEvent},
115        parameters::{Parameter, ParameterAutomation},
116        playback::{play_with_backend, AudioHandle},
117        plugin::{Plugin, PluginInfo, ProcessMode, WindowHandle},
118        window::PluginWindow,
119    };
120
121    #[cfg(feature = "cpal-backend")]
122    pub use crate::backends::CpalBackend;
123}
124
125#[cfg(test)]
126mod tests {
127    use super::*;
128
129    #[test]
130    fn test_host_creation() {
131        let host = Vst3Host::new();
132        assert!(host.is_ok());
133    }
134
135    #[test]
136    fn new_scans_default_paths_like_default() {
137        // Regression: new() used to inherit the builder's scan_default_paths=false, while
138        // Vst3Host::default() set it true — a subtle inconsistency. They must agree now.
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}