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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#![deny(missing_copy_implementations)]
#![deny(missing_docs)]
extern crate sample;
pub use mode::Mode;
pub use peak::Peak;
pub use rms::Rms;
pub use sample::{Frame, Sample};
pub mod mode;
pub mod peak;
pub mod rms;
#[derive(Copy, Clone, Debug)]
pub struct EnvelopeDetector<F, M>
where F: Frame,
M: Mode<F>,
{
attack_gain: f32,
release_gain: f32,
last_env_frame: F,
mode: M,
}
pub type RmsEnvelopeDetector<F> = EnvelopeDetector<F, Rms<F>>;
pub type PeakEnvelopeDetector<F> = EnvelopeDetector<F, Peak<peak::FullWave>>;
fn calc_gain(n_frames: f32) -> f32 {
::std::f32::consts::E.powf(-1.0 / n_frames)
}
impl<F> EnvelopeDetector<F, Rms<F>>
where F: Frame,
{
pub fn rms(rms_window_frames: usize, attack_frames: f32, release_frames: f32) -> Self {
let rms = Rms::new(rms_window_frames);
Self::new(rms, attack_frames, release_frames)
}
pub fn set_window_frames(&mut self, n_window_frames: usize) {
self.mode.set_window_frames(n_window_frames);
}
}
impl<F> EnvelopeDetector<F, Peak<peak::FullWave>>
where F: Frame,
{
pub fn peak(attack_frames: f32, release_frames: f32) -> Self {
let peak = Peak::full_wave();
Self::new(peak, attack_frames, release_frames)
}
}
impl<F, M> EnvelopeDetector<F, M>
where F: Frame,
M: Mode<F>,
{
fn new(mode: M, attack_frames: f32, release_frames: f32) -> Self {
EnvelopeDetector {
mode: mode,
last_env_frame: F::equilibrium(),
attack_gain: calc_gain(attack_frames),
release_gain: calc_gain(release_frames),
}
}
pub fn set_attack_frames(&mut self, frames: f32) {
self.attack_gain = calc_gain(frames);
}
pub fn set_release_frames(&mut self, frames: f32) {
self.attack_gain = calc_gain(frames);
}
pub fn next(&mut self, frame: F) -> F {
let EnvelopeDetector {
attack_gain, release_gain, ref mut mode, ref mut last_env_frame,
} = *self;
let mode_frame = mode.next_frame(frame);
let new_env_frame = last_env_frame.zip_map(mode_frame, |l, m| {
let gain = if l < m { attack_gain } else { release_gain };
let diff = l.add_amp(-m.to_signed_sample());
m.add_amp(diff.mul_amp(gain.to_sample()).to_sample())
});
*last_env_frame = new_env_frame;
new_env_frame
}
pub fn next_avg(&mut self, frame: F) -> <F::Sample as Sample>::Float {
let next_frame = self.next(frame);
let equilibrium: F::Sample = Sample::equilibrium();
let sum = next_frame.channels().fold(equilibrium, |sum, s| sum.add_amp(s.to_sample()));
sum.to_float_sample() / (F::n_channels() as f32).to_sample()
}
}