RustAudio / vst-rs

VST 2.4 API implementation in rust. Create plugins or hosts. Previously rust-vst on the RustDSP group.
MIT License
1.04k stars 91 forks source link

Question: Realistic host implementations examples / Host lockup #191

Closed PetrGlad closed 2 years ago

PetrGlad commented 2 years ago

I am trying to implement plugin host app. I understand that host side is not the focus of this project but I could not find alternatives in Rust and the example from https://github.com/RustAudio/vst-rs/blob/master/examples/simple_host.rs did work for me. So I managed to send an event to the plugin (Pianoteq) and get a buffer of sound from it. Now I struggle to figure out following:

(1) What is supposed structure of a vst::host::Host impl? It's methods imply that it should have access to a plugin instance, but the example has some external var to have access to it. If I would

pub struct VstHost {
    pub plugin_instance: PluginInstance,
}
impl Host for VstHost;

and use Arc<Mutex<VstHost>> to keep it then I would have to wrap plugin_instance into, say, Option to allow initializing host without plugin yet available and then lock/set the field. But then I am not sure how to continue because I would have to lock to get access to plugin_instance field which would in turn dead-lock on host (e.g. in PluginInstance::resume()). If I use some another struct to keep instance and host, then the VstHost would not actually host anything :)

~(2) How to get continuous output from the plugin? After I send an event the sustain may potentially be minutes long, I may send another event while sustain from previous one is still there, and in general I'd want to just get a stream of audio buffers of it. Should I just call instance.process(&mut audio_buffer); repeatedly to get next portion of output samples?~ UPDATED: OK, it seems that repeated calls to instance.process(&mut audio_buffer); is the way to get continuous output.

Are there projects that use this project to implement a plugin host? Or maybe there is a better alternative for that?

PetrGlad commented 2 years ago

Solved: Implemented rodio Source that owns the output buffer. Probably there are simpler ways to do id but this one worked for me. The struct that is used to output audio in my case looks like

pub struct VstHost;
impl Host for VstHost {
}
pub struct Vst {
    pub host: Arc<Mutex<VstHost>>,
    pub plugin: Arc<Mutex<PluginInstance>>,
    pub sample_rate: f32,
}
pub struct OutputSource {
    .....
    outputs: Vec<Vec<f32>>,
    plugin: Arc<Mutex<PluginInstance>>,
}
impl Iterator for OutputSource {
...
}
impl Source for OutputSource {
....
}