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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
extern crate dsp;
extern crate time_calc as time;
#[derive(Copy, Clone, Debug)]
pub struct Volume {
maybe_prev: Option<f32>,
pub current: f32,
pub interpolation_ms: time::calc::Ms,
}
impl Volume {
pub fn new() -> Volume {
Volume {
maybe_prev: None,
current: 1.0,
interpolation_ms: 10.0,
}
}
pub fn volume(mut self, volume: f32) -> Volume {
self.current = volume;
self
}
pub fn interpolation_ms(mut self, ms: time::calc::Ms) -> Volume {
self.interpolation_ms = ms;
self
}
pub fn set(&mut self, volume: f32) {
self.current = volume;
}
}
impl<F> dsp::Node<F> for Volume
where F: dsp::Frame,
{
#[inline]
fn audio_requested(&mut self, buffer: &mut [F], sample_hz: f64) {
use dsp::{Frame, Sample};
match self.maybe_prev {
Some(prev) if prev != self.current && self.interpolation_ms > 0.0 => {
let interpolation_frames = std::cmp::min(
buffer.len(),
time::Ms(self.interpolation_ms).samples(sample_hz) as usize,
);
let volume_diff = self.current - prev;
let volume_increment = volume_diff * (1.0 / interpolation_frames as f32);
let mut volume = prev;
for idx in 0..interpolation_frames {
volume += volume_increment;
let frame = &mut buffer[idx];
*frame = frame.scale_amp(volume.to_sample());
}
for idx in interpolation_frames..buffer.len() {
let frame = &mut buffer[idx];
*frame = frame.scale_amp(volume.to_sample());
}
},
_ => for frame in buffer.iter_mut() {
*frame = frame.scale_amp(self.current.to_sample());
},
}
self.maybe_prev = Some(self.current);
}
}