1
0
Fork 0

Pass the process context to the plugin

This commit is contained in:
Robbert van der Helm 2022-02-01 17:09:23 +01:00
parent 3a1fbed4c3
commit e2e2c59d34
3 changed files with 36 additions and 8 deletions

View file

@ -18,6 +18,7 @@
extern crate nih_plug; extern crate nih_plug;
use nih_plug::{ use nih_plug::{
context::ProcessContext,
formatters, formatters,
params::{BoolParam, FloatParam, Param, Params, Range}, params::{BoolParam, FloatParam, Param, Params, Range},
plugin::{BufferConfig, BusConfig, Plugin, ProcessStatus, Vst3Plugin}, plugin::{BufferConfig, BusConfig, Plugin, ProcessStatus, Vst3Plugin},
@ -105,14 +106,23 @@ impl Plugin for Gain {
config.num_input_channels == config.num_output_channels && config.num_input_channels > 0 config.num_input_channels == config.num_output_channels && config.num_input_channels > 0
} }
fn initialize(&mut self, _bus_config: &BusConfig, _buffer_config: &BufferConfig) -> bool { fn initialize(
&mut self,
_bus_config: &BusConfig,
_buffer_config: &BufferConfig,
_context: &dyn ProcessContext,
) -> bool {
// This plugin doesn't need any special initialization, but if you need to do anything // This plugin doesn't need any special initialization, but if you need to do anything
// expensive then this would be the place. State is kept around while when the host // expensive then this would be the place. State is kept around while when the host
// reconfigures the plugin. // reconfigures the plugin.
true true
} }
fn process(&mut self, samples: &mut [&mut [f32]]) -> ProcessStatus { fn process(
&mut self,
samples: &mut [&mut [f32]],
_context: &dyn ProcessContext,
) -> ProcessStatus {
if samples.is_empty() { if samples.is_empty() {
return ProcessStatus::Error("Empty buffers"); return ProcessStatus::Error("Empty buffers");
} }

View file

@ -16,6 +16,7 @@
use std::pin::Pin; use std::pin::Pin;
use crate::context::ProcessContext;
use crate::params::Params; use crate::params::Params;
/// Basic functionality that needs to be implemented by a plugin. The wrappers will use this to /// Basic functionality that needs to be implemented by a plugin. The wrappers will use this to
@ -72,11 +73,19 @@ pub trait Plugin: Default + Send + Sync {
/// shouldn't do anything beyond returning true or false. /// shouldn't do anything beyond returning true or false.
fn accepts_bus_config(&self, config: &BusConfig) -> bool; fn accepts_bus_config(&self, config: &BusConfig) -> bool;
/// Initialize the plugin for the given bus and buffer configurations. /// Initialize the plugin for the given bus and buffer configurations. If the plugin is being
/// restored from an old state, then that state will have already been restored at this point.
/// If based on those parameters (or for any reason whatsoever) the plugin needs to introduce
/// latency, then you can do so here using the process context.
/// ///
/// Before this point, the plugin should not have done any expensive initialization. Pleaes /// Before this point, the plugin should not have done any expensive initialization. Please
/// don't be that plugin that takes twenty seconds to scan. /// don't be that plugin that takes twenty seconds to scan.
fn initialize(&mut self, bus_config: &BusConfig, buffer_config: &BufferConfig) -> bool; fn initialize(
&mut self,
bus_config: &BusConfig,
buffer_config: &BufferConfig,
context: &dyn ProcessContext,
) -> bool;
/// Process audio. To not have to worry about aliasing, the host's input buffer have already /// Process audio. To not have to worry about aliasing, the host's input buffer have already
/// been copied to the output buffers if they are not handling buffers in place (most hosts do /// been copied to the output buffers if they are not handling buffers in place (most hosts do
@ -87,7 +96,11 @@ pub trait Plugin: Default + Send + Sync {
/// assymetric /// assymetric
/// TODO: Handle FTZ stuff on the wrapper side and mention that this has been handled /// TODO: Handle FTZ stuff on the wrapper side and mention that this has been handled
/// TODO: Pass transport and other context information to the plugin /// TODO: Pass transport and other context information to the plugin
fn process(&mut self, samples: &mut [&mut [f32]]) -> ProcessStatus; fn process(
&mut self,
samples: &mut [&mut [f32]],
context: &dyn ProcessContext,
) -> ProcessStatus;
} }
/// Provides auxiliary metadata needed for a VST3 plugin. /// Provides auxiliary metadata needed for a VST3 plugin.

View file

@ -876,7 +876,7 @@ impl<P: Plugin> IAudioProcessor for Wrapper<'_, P> {
.inner .inner
.plugin .plugin
.write() .write()
.initialize(&bus_config, &buffer_config) .initialize(&bus_config, &buffer_config, self.inner.as_ref())
{ {
// Preallocate enough room in the output slices vector so we can convert a `*mut *mut // Preallocate enough room in the output slices vector so we can convert a `*mut *mut
// f32` to a `&mut [&mut f32]` in the process call // f32` to a `&mut [&mut f32]` in the process call
@ -995,7 +995,12 @@ impl<P: Plugin> IAudioProcessor for Wrapper<'_, P> {
} }
} }
match self.inner.plugin.write().process(&mut output_slices) { match self
.inner
.plugin
.write()
.process(&mut output_slices, self.inner.as_ref())
{
ProcessStatus::Error(err) => { ProcessStatus::Error(err) => {
nih_debug_assert_failure!("Process error: {}", err); nih_debug_assert_failure!("Process error: {}", err);