1
0
Fork 0

Add an Iterator implementation for smoothers

This commit is contained in:
Robbert van der Helm 2022-04-04 17:51:51 +02:00
parent 6f01097b03
commit 98d725d24f

View file

@ -49,6 +49,14 @@ pub struct Smoother<T> {
block_values: AtomicRefCell<Vec<T>>, block_values: AtomicRefCell<Vec<T>>,
} }
/// An iterator that continuously produces smoothed values. Can be used as an alternative to the
/// built-in block-based smoothing API. Since the iterator itself is infinite, you can use
/// [`Smoother::is_smoothing()`] and [`Smoother::steps_left()`] to get information on the current
/// smoothing status.
pub struct SmootherIter<'a, T> {
smoother: &'a Smoother<T>,
}
impl<T: Default> Default for Smoother<T> { impl<T: Default> Default for Smoother<T> {
fn default() -> Self { fn default() -> Self {
Self { Self {
@ -63,6 +71,27 @@ impl<T: Default> Default for Smoother<T> {
} }
} }
// We don't have a trait describing the smoother's functions so we need to duplicate this
// TODO: Maybe add a trait at some point so we can deduplicate some of the functions from this file.
// Needing a trait like that is not ideal though
impl Iterator for SmootherIter<'_, f32> {
type Item = f32;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
Some(self.smoother.next())
}
}
impl Iterator for SmootherIter<'_, i32> {
type Item = i32;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
Some(self.smoother.next())
}
}
impl<T: Default> Smoother<T> { impl<T: Default> Smoother<T> {
/// Use the specified style for the smoothing. /// Use the specified style for the smoothing.
pub fn new(style: SmoothingStyle) -> Self { pub fn new(style: SmoothingStyle) -> Self {
@ -91,6 +120,11 @@ impl<T: Default> Smoother<T> {
self.steps_left() > 0 self.steps_left() > 0
} }
#[inline]
pub fn iter(&self) -> SmootherIter<T> {
SmootherIter { smoother: self }
}
/// Allocate memory to store smoothed values for an entire block of audio. Call this in /// Allocate memory to store smoothed values for an entire block of audio. Call this in
/// [`Plugin::initialize()`][crate::prelude::Plugin::initialize()] with the same max block size you are /// [`Plugin::initialize()`][crate::prelude::Plugin::initialize()] with the same max block size you are
/// going to pass to [`Buffer::iter_blocks()`][crate::prelude::Buffer::iter_blocks()]. /// going to pass to [`Buffer::iter_blocks()`][crate::prelude::Buffer::iter_blocks()].
@ -157,14 +191,12 @@ impl Smoother<f32> {
/// # Panics /// # Panics
/// ///
/// Panics if this function is called again while another block value slice is still alive. /// Panics if this function is called again while another block value slice is still alive.
#[inline]
pub fn next_block(&self, block: &Block) -> Option<AtomicRefMut<[f32]>> { pub fn next_block(&self, block: &Block) -> Option<AtomicRefMut<[f32]>> {
self.next_block_mapped(block, |x| x) self.next_block_mapped(block, |x| x)
} }
/// The same as [`next_block()`][Self::next_block()], but with a function applied to each /// The same as [`next_block()`][Self::next_block()], but with a function applied to each
/// produced value. Useful when applying modulation to a smoothed parameter. /// produced value. Useful when applying modulation to a smoothed parameter.
#[inline]
pub fn next_block_mapped( pub fn next_block_mapped(
&self, &self,
block: &Block, block: &Block,
@ -270,14 +302,12 @@ impl Smoother<i32> {
/// # Panics /// # Panics
/// ///
/// Panics if this function is called again while another block value slice is still alive. /// Panics if this function is called again while another block value slice is still alive.
#[inline]
pub fn next_block(&self, block: &Block) -> Option<AtomicRefMut<[i32]>> { pub fn next_block(&self, block: &Block) -> Option<AtomicRefMut<[i32]>> {
self.next_block_mapped(block, |x| x) self.next_block_mapped(block, |x| x)
} }
/// The same as [`next_block()`][Self::next_block()], but with a function applied to each /// The same as [`next_block()`][Self::next_block()], but with a function applied to each
/// produced value. Useful when applying modulation to a smoothed parameter. /// produced value. Useful when applying modulation to a smoothed parameter.
#[inline]
pub fn next_block_mapped( pub fn next_block_mapped(
&self, &self,
block: &Block, block: &Block,