use crate::backend::HostInterface;
use crate::buffer::AudioBufferInOut;
use crate::event::{ContextualEventHandler, RawMidiEvent, SysExEvent, Timed};
use crate::{
AudioHandler, AudioHandlerMeta, CommonAudioPortMeta, CommonPluginMeta, ContextualAudioRenderer,
};
use core::cmp;
use vecstorage::VecStorage;
pub mod vst {
pub use vst::*;
}
use self::vst::{
api::Events,
buffer::AudioBuffer,
channels::ChannelInfo,
event::{Event as VstEvent, MidiEvent as VstMidiEvent, SysExEvent as VstSysExEvent},
plugin::{Category, HostCallback, Info},
};
pub trait VstPluginMeta: CommonPluginMeta + AudioHandlerMeta {
fn plugin_id(&self) -> i32;
fn category(&self) -> Category;
}
pub struct VstPluginWrapper<P> {
plugin: P,
host: HostCallback,
inputs_f32: VecStorage<&'static [f32]>,
outputs_f32: VecStorage<&'static [f32]>,
inputs_f64: VecStorage<&'static [f64]>,
outputs_f64: VecStorage<&'static [f64]>,
}
impl<P> VstPluginWrapper<P>
where
P: CommonAudioPortMeta
+ VstPluginMeta
+ AudioHandler
+ ContextualEventHandler<Timed<RawMidiEvent>, HostCallback>
+ ContextualAudioRenderer<f32, HostCallback>
+ ContextualAudioRenderer<f64, HostCallback>,
for<'a> P: ContextualEventHandler<Timed<SysExEvent<'a>>, HostCallback>,
{
pub fn get_info(&self) -> Info {
trace!("get_info");
Info {
name: self.plugin.name().to_string(),
inputs: self.plugin.max_number_of_audio_inputs() as i32,
outputs: self.plugin.max_number_of_audio_outputs() as i32,
unique_id: self.plugin.plugin_id(),
category: self.plugin.category(),
..Info::default()
}
}
pub fn new(plugin: P, host: HostCallback) -> Self {
Self {
inputs_f32: VecStorage::with_capacity(plugin.max_number_of_audio_inputs()),
outputs_f32: VecStorage::with_capacity(plugin.max_number_of_audio_outputs()),
inputs_f64: VecStorage::with_capacity(plugin.max_number_of_audio_inputs()),
outputs_f64: VecStorage::with_capacity(plugin.max_number_of_audio_outputs()),
plugin,
host,
}
}
pub fn host(&self) -> &HostCallback {
&self.host
}
pub fn process<'b>(&mut self, buffer: &mut AudioBuffer<'b, f32>) {
let number_of_frames = buffer.samples();
let (input_buffers, mut output_buffers) = buffer.split();
let mut inputs = self.inputs_f32.vec_guard();
for i in 0..cmp::min(inputs.capacity(), input_buffers.len()) {
inputs.push(input_buffers.get(i));
}
let mut outputs = self.outputs_f32.vec_guard();
for i in 0..cmp::min(outputs.capacity(), output_buffers.len()) {
outputs.push(output_buffers.get_mut(i));
}
let mut audio_buffer =
AudioBufferInOut::new(inputs.as_slice(), outputs.as_mut_slice(), number_of_frames);
self.plugin.render_buffer(&mut audio_buffer, &mut self.host);
}
pub fn process_f64<'b>(&mut self, buffer: &mut AudioBuffer<'b, f64>) {
let number_of_frames = buffer.samples();
let (input_buffers, mut output_buffers) = buffer.split();
let mut inputs = self.inputs_f64.vec_guard();
for i in 0..cmp::min(inputs.capacity(), input_buffers.len()) {
inputs.push(input_buffers.get(i));
}
let mut outputs = self.outputs_f64.vec_guard();
for i in 0..cmp::min(outputs.capacity(), output_buffers.len()) {
outputs.push(output_buffers.get_mut(i));
}
let mut audio_buffer =
AudioBufferInOut::new(inputs.as_slice(), outputs.as_mut_slice(), number_of_frames);
self.plugin.render_buffer(&mut audio_buffer, &mut self.host);
}
pub fn get_input_info(&self, input_index: i32) -> ChannelInfo {
trace!("get_input_info({})", input_index);
ChannelInfo::new(
self.plugin.audio_input_name(input_index as usize),
None,
true,
None,
)
}
pub fn get_output_info(&self, output_index: i32) -> ChannelInfo {
trace!("get_output_info({})", output_index);
ChannelInfo::new(
self.plugin.audio_output_name(output_index as usize),
None,
true,
None,
)
}
pub fn process_events(&mut self, events: &Events) {
trace!("process_events");
for e in events.events() {
match e {
VstEvent::SysEx(VstSysExEvent {
payload,
delta_frames,
..
}) => {
let event = Timed {
time_in_frames: delta_frames as u32,
event: SysExEvent::new(payload),
};
self.plugin.handle_event(event, &mut self.host);
}
VstEvent::Midi(VstMidiEvent {
data, delta_frames, ..
}) => {
let event = Timed {
time_in_frames: delta_frames as u32,
event: RawMidiEvent::new(&data),
};
self.plugin.handle_event(event, &mut self.host);
}
_ => (),
}
}
}
pub fn set_sample_rate(&mut self, sample_rate: f64) {
trace!("sample_rate: {}", sample_rate);
self.plugin.set_sample_rate(sample_rate);
}
}
impl HostInterface for HostCallback {
fn output_initialized(&self) -> bool {
false
}
}
#[macro_export]
macro_rules! vst_init {
(fn $function_name:ident() -> $return_type:ty
$body:block
) => {
fn $function_name () -> $return_type
$body
struct VstWrapperWrapper {
wrapper: $crate::backend::vst_backend::VstPluginWrapper<$return_type>
}
impl Default for VstWrapperWrapper {
fn default() -> Self {
unreachable!()
}
}
impl vst::plugin::Plugin for VstWrapperWrapper
{
fn get_info(&self) -> vst::plugin::Info {
self.wrapper.get_info()
}
fn new(host: vst::plugin::HostCallback) -> Self
where
Self: Sized + Default
{
VstWrapperWrapper
{
wrapper: $crate::backend::vst_backend::VstPluginWrapper::new($function_name(), host)
}
}
fn init(&mut self) {
let sample_rate =
if let Some(vst::api::TimeInfo{sample_rate: sr, ..}) =
vst::host::Host::get_time_info(
self.wrapper.host(),
0 )
{
Some(sr)
} else {
None
};
if let Some(sr) = sample_rate {
self.wrapper.set_sample_rate(sr);
}
}
#[inline]
fn process<'b>(&mut self, buffer: &mut vst::buffer::AudioBuffer<'b, f32>) {
self.wrapper.process(buffer);
}
#[inline]
fn process_f64<'b>(&mut self, buffer: &mut vst::buffer::AudioBuffer<'b, f64>) {
self.wrapper.process_f64(buffer);
}
fn get_input_info(&self, input_index: i32) -> vst::channels::ChannelInfo {
self.wrapper.get_input_info(input_index)
}
fn get_output_info(&self, output_index: i32) -> vst::channels::ChannelInfo {
self.wrapper.get_output_info(output_index)
}
#[inline]
fn process_events(&mut self, events: &vst::api::Events) {
self.wrapper.process_events(events)
}
}
plugin_main!(VstWrapperWrapper);
}
}