Add functions for allocating block smoothers
This commit is contained in:
parent
892aef7e37
commit
d470a1db5a
|
@ -67,6 +67,10 @@ pub trait Param: Display {
|
||||||
/// reset to the current value.
|
/// reset to the current value.
|
||||||
fn update_smoother(&mut self, sample_rate: f32, reset: bool);
|
fn update_smoother(&mut self, sample_rate: f32, reset: bool);
|
||||||
|
|
||||||
|
/// Allocate memory for block-based smoothing. The [crate::Plugin::initialize_block_smoothers()]
|
||||||
|
/// method will do this for every smoother.
|
||||||
|
fn initialize_block_smoother(&mut self, max_block_size: usize);
|
||||||
|
|
||||||
/// Internal implementation detail for implementing [internals::Params]. This should not be used
|
/// Internal implementation detail for implementing [internals::Params]. This should not be used
|
||||||
/// directly.
|
/// directly.
|
||||||
fn as_ptr(&self) -> internals::ParamPtr;
|
fn as_ptr(&self) -> internals::ParamPtr;
|
||||||
|
|
|
@ -122,6 +122,8 @@ impl Param for BoolParam {
|
||||||
// Can't really smooth a binary parameter now can you
|
// Can't really smooth a binary parameter now can you
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn initialize_block_smoother(&mut self, _max_block_size: usize) {}
|
||||||
|
|
||||||
fn as_ptr(&self) -> ParamPtr {
|
fn as_ptr(&self) -> ParamPtr {
|
||||||
ParamPtr::BoolParam(self as *const BoolParam as *mut BoolParam)
|
ParamPtr::BoolParam(self as *const BoolParam as *mut BoolParam)
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,6 +140,10 @@ impl<T: Enum> Param for EnumParam<T> {
|
||||||
self.inner.update_smoother(sample_rate, reset)
|
self.inner.update_smoother(sample_rate, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn initialize_block_smoother(&mut self, max_block_size: usize) {
|
||||||
|
self.inner.initialize_block_smoother(max_block_size)
|
||||||
|
}
|
||||||
|
|
||||||
fn as_ptr(&self) -> ParamPtr {
|
fn as_ptr(&self) -> ParamPtr {
|
||||||
self.inner.as_ptr()
|
self.inner.as_ptr()
|
||||||
}
|
}
|
||||||
|
@ -198,6 +202,10 @@ impl Param for EnumParamInner {
|
||||||
self.inner.update_smoother(sample_rate, reset)
|
self.inner.update_smoother(sample_rate, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn initialize_block_smoother(&mut self, max_block_size: usize) {
|
||||||
|
self.inner.initialize_block_smoother(max_block_size)
|
||||||
|
}
|
||||||
|
|
||||||
fn as_ptr(&self) -> ParamPtr {
|
fn as_ptr(&self) -> ParamPtr {
|
||||||
ParamPtr::EnumParam(self as *const EnumParamInner as *mut EnumParamInner)
|
ParamPtr::EnumParam(self as *const EnumParamInner as *mut EnumParamInner)
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,22 @@ impl ParamPtr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocate memory for block-based smoothing. The [crate::Plugin::initialize_block_smoothers()]
|
||||||
|
/// method will do this for every smoother.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Calling this function is only safe as long as the object this `ParamPtr` was created for is
|
||||||
|
/// still alive.
|
||||||
|
pub unsafe fn initialize_block_smoother(&mut self, max_block_size: usize) {
|
||||||
|
match &self {
|
||||||
|
ParamPtr::FloatParam(p) => (**p).initialize_block_smoother(max_block_size),
|
||||||
|
ParamPtr::IntParam(p) => (**p).initialize_block_smoother(max_block_size),
|
||||||
|
ParamPtr::BoolParam(p) => (**p).initialize_block_smoother(max_block_size),
|
||||||
|
ParamPtr::EnumParam(p) => (**p).initialize_block_smoother(max_block_size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Set this parameter based on a string. Returns whether the updating succeeded. That can fail
|
/// Set this parameter based on a string. Returns whether the updating succeeded. That can fail
|
||||||
/// if the string cannot be parsed.
|
/// if the string cannot be parsed.
|
||||||
///
|
///
|
||||||
|
|
|
@ -186,6 +186,10 @@ macro_rules! impl_plainparam {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn initialize_block_smoother(&mut self, max_block_size: usize) {
|
||||||
|
self.smoothed.initialize_block_smoother(max_block_size);
|
||||||
|
}
|
||||||
|
|
||||||
fn as_ptr(&self) -> ParamPtr {
|
fn as_ptr(&self) -> ParamPtr {
|
||||||
ParamPtr::$ty(self as *const $ty as *mut $ty)
|
ParamPtr::$ty(self as *const $ty as *mut $ty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use atomic_float::AtomicF32;
|
use atomic_float::AtomicF32;
|
||||||
|
use parking_lot::Mutex;
|
||||||
use std::sync::atomic::{AtomicI32, Ordering};
|
use std::sync::atomic::{AtomicI32, Ordering};
|
||||||
|
|
||||||
/// Controls if and how parameters gets smoothed.
|
/// Controls if and how parameters gets smoothed.
|
||||||
|
@ -37,6 +38,10 @@ pub struct Smoother<T> {
|
||||||
current: AtomicF32,
|
current: AtomicF32,
|
||||||
/// The value we're smoothing towards
|
/// The value we're smoothing towards
|
||||||
target: T,
|
target: T,
|
||||||
|
|
||||||
|
/// A dense buffer containing smoothed values for an entire block of audio. Useful when using
|
||||||
|
/// [crate::Buffer::iter_blocks()] to process small blocks of audio multiple times.
|
||||||
|
block_values: Mutex<Vec<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Default> Default for Smoother<T> {
|
impl<T: Default> Default for Smoother<T> {
|
||||||
|
@ -47,6 +52,8 @@ impl<T: Default> Default for Smoother<T> {
|
||||||
step_size: Default::default(),
|
step_size: Default::default(),
|
||||||
current: AtomicF32::new(0.0),
|
current: AtomicF32::new(0.0),
|
||||||
target: Default::default(),
|
target: Default::default(),
|
||||||
|
|
||||||
|
block_values: Mutex::new(Vec::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,6 +77,15 @@ impl<T: Default> Smoother<T> {
|
||||||
pub fn is_smoothing(&self) -> bool {
|
pub fn is_smoothing(&self) -> bool {
|
||||||
self.steps_left.load(Ordering::Relaxed) > 0
|
self.steps_left.load(Ordering::Relaxed) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocate memory to store smoothed values for an entire block of audio. Call this in
|
||||||
|
/// [crate::Plugin::initialize()] with the same max block size you are going to pass to
|
||||||
|
/// [crate::Buffer::iter_blocks()].
|
||||||
|
pub fn initialize_block_smoother(&mut self, max_block_size: usize) {
|
||||||
|
self.block_values
|
||||||
|
.lock()
|
||||||
|
.resize_with(max_block_size, || T::default());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are not iterators for the sole reason that this will always yield a value, and needing to
|
// These are not iterators for the sole reason that this will always yield a value, and needing to
|
||||||
|
|
Loading…
Reference in a new issue