diff options
author | Grant Shangreaux <grant@unabridgedsoftware.com> | 2021-11-11 10:20:59 -0600 |
---|---|---|
committer | Grant Shangreaux <grant@unabridgedsoftware.com> | 2021-11-11 10:20:59 -0600 |
commit | a17829f5412ee0757574b34e34ce78b2975df1fe (patch) | |
tree | fb7e09aa7ee101bf48c824634f1e79428c0529ed /klangfarbrs/src/adsr.rs | |
parent | 2b22b39b08c499798efcb874db6e6268eef43a52 (diff) |
Add: poorly implemented but working amplitude envelope
Diffstat (limited to 'klangfarbrs/src/adsr.rs')
-rw-r--r-- | klangfarbrs/src/adsr.rs | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/klangfarbrs/src/adsr.rs b/klangfarbrs/src/adsr.rs index 682cc8a..9d51ba3 100644 --- a/klangfarbrs/src/adsr.rs +++ b/klangfarbrs/src/adsr.rs @@ -1,16 +1,18 @@ -use crate::{Millisecond, Amplitude}; +use super::{Millisecond, Amplitude, SamplesPerSecond}; pub struct Envelope { - attack: Vec<Amplitude>, - decay: Vec<Amplitude>, - release: Vec<Amplitude>, + pub attack: Vec<Amplitude>, + pub decay: Vec<Amplitude>, + pub release: Vec<Amplitude>, } impl Envelope { - pub fn new(attack: Millisecond, decay: Millisecond, sustain: Amplitude, release: Millisecond) -> Self { - let attack = vec![sustain; attack as usize]; - let decay = vec![sustain; decay as usize]; - let release = vec![sustain; release as usize]; + pub fn new( + attack: Millisecond, decay: Millisecond, sustain: Amplitude, release: Millisecond, sample_rate: SamplesPerSecond + ) -> Self { + let attack = interpolate(0.0, 1.0, ms_to_samples(attack, sample_rate)); + let decay = interpolate(1.0, sustain, ms_to_samples(decay, sample_rate)); + let release = interpolate(sustain, 0.0, ms_to_samples(release, sample_rate)); Self{attack, decay, release} } @@ -20,13 +22,45 @@ impl Envelope { } } +fn interpolate(start: Amplitude, end: Amplitude, milliseconds: Millisecond) -> Vec<Amplitude> { + let step_size = (end - start) / milliseconds as f32; + let mut amps = vec!(); + let mut current_val = start + step_size; + + for i in 0..=milliseconds { + if i == 0 { + amps.push(start) + } else if i == milliseconds { + amps.push(end) + } else { + amps.push(current_val); + current_val += step_size; + } + } + + amps +} + +fn ms_to_samples(ms: Millisecond, sample_rate: SamplesPerSecond) -> u32 { + let multiplier = sample_rate as u32 / 1000; + multiplier * ms +} + #[cfg(test)] mod tests { use super::*; #[test] fn it_has_expected_total_length() { - let total = Envelope::new(10, 10, 1.0, 10).len(); - assert_eq! (30, total) + let expected = 3 + ms_to_samples(30, 48000.0) as usize; + let total = Envelope::new(10, 10, 1.0, 10, 48000.0).len(); + assert_eq! (expected, total) + } + + #[test] + fn interpolate_works() { + let expected = vec![0.0, 0.2, 0.4, 0.6, 0.8, 1.0]; + let result = interpolate(0.0, 1.0, 5); + assert_eq!(expected, result) } } |