Add an Iterator implementation for smoothers
This commit is contained in:
parent
6f01097b03
commit
98d725d24f
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue