dasp_interpolate/
linear.rs

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