Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- Added `equilibrium_padded` constructors for `Floor`, `Linear`, and `Sinc`
interpolators.
- Renamed `window-hanning` to `window-hann`
- Made `IntoInterleavedSamples` and `IntoInterleavedSamplesIterator` stop
yielding samples when the underlying signal gets exhausted. This is a breaking
Expand Down
21 changes: 21 additions & 0 deletions dasp_interpolate/src/floor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,27 @@ impl<F> Floor<F> {
pub fn new(left: F) -> Floor<F> {
Floor { left: left }
}

/// Create a new Floor Interpolator padded with equilibrium.
///
/// ### Required Features
///
/// - When using `dasp_interpolate`, this item requires the **floor** feature to be enabled.
/// - When using `dasp`, this item requires the **interpolate-floor** feature to be enabled.
///
/// ```
/// use dasp_interpolate::floor::Floor;
///
/// let interp = Floor::<f32>::equilibrium_padded();
/// ```
pub fn equilibrium_padded() -> Floor<F>
where
F: Frame,
{
Floor {
left: F::EQUILIBRIUM,
}
}
}

impl<F> Interpolator for Floor<F>
Expand Down
24 changes: 24 additions & 0 deletions dasp_interpolate/src/linear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,30 @@ impl<F> Linear<F> {
right: right,
}
}

/// Create a new Linear Interpolator padded with equilibrium.
///
/// Both the left and right frames are initialized to `Frame::EQUILIBRIUM`.
///
/// ### Required Features
///
/// - When using `dasp_interpolate`, this item requires the **linear** feature to be enabled.
/// - When using `dasp`, this item requires the **interpolate-linear** feature to be enabled.
///
/// ```
/// use dasp_interpolate::linear::Linear;
///
/// let interp = Linear::<f32>::equilibrium_padded();
/// ```
pub fn equilibrium_padded() -> Linear<F>
where
F: Frame,
{
Linear {
left: F::EQUILIBRIUM,
right: F::EQUILIBRIUM,
}
}
}

impl<F> Interpolator for Linear<F>
Expand Down
33 changes: 33 additions & 0 deletions dasp_interpolate/src/sinc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,39 @@ impl<S> Sinc<S> {
}
}

/// Create a new **Sinc** interpolator with the given ring buffer padded with equilibrium.
///
/// The given ring buffer should have a length twice that of the desired sinc interpolation
/// `depth`.
///
/// The initial contents of the ring_buffer are replaced with `Frame::EQUILIBRIUM`.
///
/// **panic!**s if the given ring buffer's length is not a multiple of `2`.
///
/// ### Required Features
///
/// - When using `dasp_interpolate`, this item requires the **sinc** feature to be enabled.
/// - When using `dasp`, this item requires the **interpolate-sinc** feature to be enabled.
///
/// ```
/// use dasp_interpolate::sinc::Sinc;
/// use dasp_ring_buffer as ring_buffer;
///
/// let frames = ring_buffer::Fixed::from([1.0; 8]);
/// let interp = Sinc::equilibrium_padded(frames);
/// ```
pub fn equilibrium_padded(mut frames: ring_buffer::Fixed<S>) -> Self
where
S: ring_buffer::SliceMut,
S::Element: Frame,
{
assert!(frames.len() % 2 == 0);
for frame in frames.iter_mut() {
*frame = <S::Element as Frame>::EQUILIBRIUM;
}
Sinc { frames, idx: 0 }
}

fn depth(&self) -> usize
where
S: ring_buffer::Slice,
Expand Down
41 changes: 40 additions & 1 deletion dasp_signal/tests/interpolate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Tests for the `Converter` and `Interpolator` traits

use dasp_interpolate::{floor::Floor, linear::Linear, sinc::Sinc};
use dasp_interpolate::{floor::Floor, linear::Linear, sinc::Sinc, Interpolator};
use dasp_ring_buffer as ring_buffer;
use dasp_signal::{self as signal, interpolate::Converter, Signal};

Expand All @@ -23,6 +23,17 @@ fn test_floor_converter() {
assert_eq!(conv.next(), 2.0);
}

#[test]
fn test_floor_equilibrium_padded() {
let mut interp = Floor::<f64>::equilibrium_padded();

assert_eq!(interp.interpolate(0.0), 0.0);
assert_eq!(interp.interpolate(0.5), 0.0);

interp.next_source_frame(1.0);
assert_eq!(interp.interpolate(0.5), 1.0);
}

#[test]
fn test_linear_converter() {
let frames: [f64; 3] = [0.0, 1.0, 2.0];
Expand All @@ -42,6 +53,21 @@ fn test_linear_converter() {
assert_eq!(conv.next(), 1.0);
}

#[test]
fn test_linear_equilibrium_padded() {
let mut interp = Linear::<f64>::equilibrium_padded();

assert_eq!(interp.interpolate(0.0), 0.0);
assert_eq!(interp.interpolate(0.5), 0.0);

interp.next_source_frame(1.0);
assert_eq!(interp.interpolate(0.0), 0.0);
assert_eq!(interp.interpolate(0.5), 0.5);

interp.next_source_frame(2.0);
assert_eq!(interp.interpolate(0.5), 1.5);
}

#[test]
fn test_scale_playback_rate() {
// Scale the playback rate by `0.5`
Expand Down Expand Up @@ -71,3 +97,16 @@ fn test_sinc() {
None
);
}

#[test]
fn test_sinc_equilibrium_padded_clears_supplied_buffer() {
let frames = ring_buffer::Fixed::from(vec![1.0_f64; 50]);
let mut interp = Sinc::equilibrium_padded(frames);

assert_eq!(interp.interpolate(0.0), 0.0);
assert_eq!(interp.interpolate(0.5), 0.0);

interp.next_source_frame(1.0);
let sample = interp.interpolate(0.0);
assert!(sample.is_finite());
}
Loading