dasp_interpolate/linear.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
//! A linear interpolator implementation.
//!
//! ### Required Features
//!
//! - When using `dasp_interpolate`, this module requires the **linear** feature to be enabled.
//! - When using `dasp`, this module requires the **interpolate-linear** feature to be enabled.
use crate::Interpolator;
use dasp_frame::Frame;
use dasp_sample::{Duplex, Sample};
/// Interpolator that interpolates linearly between the previous value and the next value
///
/// ### 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.
pub struct Linear<F> {
left: F,
right: F,
}
impl<F> Linear<F> {
/// Create a new Linear Interpolator, where `left` and `right` are the first two frames to be
/// interpolated.
///
/// ### 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.
pub fn new(left: F, right: F) -> Linear<F> {
Linear {
left: left,
right: right,
}
}
}
impl<F> Interpolator for Linear<F>
where
F: Frame,
F::Sample: Duplex<f64>,
{
type Frame = F;
/// Converts linearly from the previous value, using the next value to interpolate. It is
/// possible, although not advisable, to provide an x > 1.0 or < 0.0, but this will just
/// continue to be a linear ramp in one direction or another.
fn interpolate(&self, x: f64) -> Self::Frame {
self.left.zip_map(self.right, |l, r| {
let l_f = l.to_sample::<f64>();
let r_f = r.to_sample::<f64>();
let diff = r_f - l_f;
((diff * x) + l_f).to_sample::<<Self::Frame as Frame>::Sample>()
})
}
fn next_source_frame(&mut self, source_frame: Self::Frame) {
self.left = self.right;
self.right = source_frame;
}
}