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}