-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathlinear.rs
67 lines (60 loc) · 2.12 KB
/
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
63
64
65
66
67
//! 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;
}
fn reset(&mut self) {
self.left = Self::Frame::EQUILIBRIUM;
self.right = Self::Frame::EQUILIBRIUM;
}
}