1
0
Fork 0

Hold the RwLock guard in the process context

This avoids having to constantly acquire a new lock.
This commit is contained in:
Robbert van der Helm 2022-02-04 23:03:11 +01:00
parent ce3da8ea44
commit bbc190c67f
5 changed files with 22 additions and 16 deletions

View file

@ -111,7 +111,7 @@ impl Plugin for Gain {
&mut self,
_bus_config: &BusConfig,
_buffer_config: &BufferConfig,
_context: &impl ProcessContext,
_context: &mut impl ProcessContext,
) -> bool {
// 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
@ -119,7 +119,11 @@ impl Plugin for Gain {
true
}
fn process(&mut self, buffer: &mut Buffer, _context: &impl ProcessContext) -> ProcessStatus {
fn process(
&mut self,
buffer: &mut Buffer,
_context: &mut impl ProcessContext,
) -> ProcessStatus {
for samples in buffer.iter_mut() {
// Smoothing is optionally built into the parameters themselves
let gain = self.params.gain.smoothed.next();

View file

@ -145,14 +145,14 @@ impl Plugin for Sine {
&mut self,
_bus_config: &BusConfig,
buffer_config: &BufferConfig,
_context: &impl ProcessContext,
_context: &mut impl ProcessContext,
) -> bool {
self.sample_rate = buffer_config.sample_rate;
true
}
fn process(&mut self, buffer: &mut Buffer, context: &impl ProcessContext) -> ProcessStatus {
fn process(&mut self, buffer: &mut Buffer, context: &mut impl ProcessContext) -> ProcessStatus {
let mut next_event = context.next_midi_event();
for (sample_id, samples) in buffer.iter_mut().enumerate() {
// Smoothing is optionally built into the parameters themselves

View file

@ -48,7 +48,7 @@ pub trait ProcessContext {
/// TODO: Rethink this API, both in terms of ergonomics, and if we can do this in a way that
/// doesn't require locks (because of the thread safe-ness, which we don't really need
/// here)
fn next_midi_event(&self) -> Option<NoteEvent>;
fn next_midi_event(&mut self) -> Option<NoteEvent>;
// // TODO: Add this next
// fn set_parameter<P>(&self, param: &P, value: P::Plain)

View file

@ -88,7 +88,7 @@ pub trait Plugin: Default + Send + Sync {
&mut self,
bus_config: &BusConfig,
buffer_config: &BufferConfig,
context: &impl ProcessContext,
context: &mut impl ProcessContext,
) -> bool {
true
}
@ -103,7 +103,7 @@ pub trait Plugin: Default + Send + Sync {
/// TODO: Provide a way to access auxiliary input channels if the IO configuration is
/// assymetric
/// TODO: Pass transport and other context information to the plugin
fn process(&mut self, buffer: &mut Buffer, context: &impl ProcessContext) -> ProcessStatus;
fn process(&mut self, buffer: &mut Buffer, context: &mut impl ProcessContext) -> ProcessStatus;
}
/// Provides auxiliary metadata needed for a VST3 plugin.

View file

@ -20,7 +20,7 @@
use crossbeam::atomic::AtomicCell;
use lazy_static::lazy_static;
use parking_lot::RwLock;
use parking_lot::{RwLock, RwLockWriteGuard};
use std::cmp;
use std::collections::{HashMap, VecDeque};
use std::ffi::c_void;
@ -152,6 +152,7 @@ pub(crate) struct Wrapper<P: Plugin> {
/// unnecessary atomic operations to lock the uncontested RwLocks.
struct WrapperProcessContext<'a, P: Plugin> {
inner: &'a WrapperInner<P>,
input_events_guard: RwLockWriteGuard<'a, VecDeque<NoteEvent>>,
}
impl<P: Plugin> ProcessContext for WrapperProcessContext<'_, P> {
@ -167,10 +168,8 @@ impl<P: Plugin> ProcessContext for WrapperProcessContext<'_, P> {
}
}
fn next_midi_event(&self) -> Option<NoteEvent> {
// TODO: Instead of having to lock this queue, move the lock guard into
// `WrapperProcessContext`. That's the whole reason this was split up.
self.inner.input_events.write().pop_front()
fn next_midi_event(&mut self) -> Option<NoteEvent> {
self.input_events_guard.pop_front()
}
}
@ -293,7 +292,10 @@ impl<P: Plugin> WrapperInner<P> {
}
pub fn make_process_context(&self) -> WrapperProcessContext<'_, P> {
WrapperProcessContext { inner: self }
WrapperProcessContext {
inner: self,
input_events_guard: self.input_events.write(),
}
}
/// Convenience function for setting a value for a parameter as triggered by a VST3 parameter
@ -607,7 +609,7 @@ impl<P: Plugin> IComponent for Wrapper<P> {
self.inner.plugin.write().initialize(
&bus_config,
&buffer_config,
&self.inner.make_process_context(),
&mut self.inner.make_process_context(),
);
}
@ -994,7 +996,7 @@ impl<P: Plugin> IAudioProcessor for Wrapper<P> {
if self.inner.plugin.write().initialize(
&bus_config,
&buffer_config,
&self.inner.make_process_context(),
&mut self.inner.make_process_context(),
) {
// 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
@ -1173,7 +1175,7 @@ impl<P: Plugin> IAudioProcessor for Wrapper<P> {
.plugin
.write()
// SAFETY: Same here
.process(&mut output_buffer, &self.inner.make_process_context())
.process(&mut output_buffer, &mut self.inner.make_process_context())
{
ProcessStatus::Error(err) => {
nih_debug_assert_failure!("Process error: {}", err);