diff options
-rw-r--r-- | klangfarb/main.gd | 17 | ||||
-rw-r--r-- | klangfarbrs/src/envelope.rs (renamed from klangfarbrs/src/adsr.rs) | 29 | ||||
-rw-r--r-- | klangfarbrs/src/lib.rs | 32 |
3 files changed, 49 insertions, 29 deletions
diff --git a/klangfarb/main.gd b/klangfarb/main.gd index 268934f..751527a 100644 --- a/klangfarb/main.gd +++ b/klangfarb/main.gd @@ -57,19 +57,19 @@ func _check_waveform(): func _process(_delta): if self.is_playing(): - synth.apply_bend(apply_bend) - synth.frequency(freq) - synth.phasor_bend(phasor_bend) +# synth.apply_bend(apply_bend) +# synth.frequency(freq) +# synth.phasor_bend(phasor_bend) synth.frequency_modulation(frequency_modulation) - synth.fm_frequency(fm_multiplier * freq) +# synth.fm_frequency(fm_multiplier * freq) synth.fm_depth(fm_index) synth.continuous(continuous) _check_waveform() _fill_buffer() func _ready() -> void: - # buffer length of 100ms gives us ~realtime response to input changes - self.stream.buffer_length = 0.1 + # buffer length of 10ms gives us ~realtime response to input changes + self.stream.buffer_length = 0.05 # ensure Godot/Sine have the same sample rate synth.set_sample_rate(self.stream.mix_rate) # get our AudioStreamPlayback object @@ -80,10 +80,13 @@ func _ready() -> void: func _input(event): # Mouse in viewport coordinates. - if event is InputEventMouseButton: + if event is InputEventMouseButton && event.is_pressed(): print("Mouse Click/Unclick at: ", event.position) + synth.trigger() elif event is InputEventMouseMotion: freq = event.position.x + synth.frequency(freq) # phasor_bend.x = event.position.x / 1024 # phasor_bend.y = event.position.y / 600 fm_multiplier = 600 / (event.position.y + 1) + synth.fm_frequency(fm_multiplier * freq) diff --git a/klangfarbrs/src/adsr.rs b/klangfarbrs/src/envelope.rs index 9d51ba3..3da7977 100644 --- a/klangfarbrs/src/adsr.rs +++ b/klangfarbrs/src/envelope.rs @@ -4,6 +4,7 @@ pub struct Envelope { pub attack: Vec<Amplitude>, pub decay: Vec<Amplitude>, pub release: Vec<Amplitude>, + pub index: usize, } impl Envelope { @@ -14,7 +15,7 @@ impl Envelope { 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} + Self { attack, decay, release, index: 0 } } pub fn len(&self) -> usize { @@ -22,6 +23,32 @@ impl Envelope { } } +impl Iterator for Envelope { + type Item = Amplitude; + + fn next(&mut self) -> Option<Self::Item> { + let idx = self.index; + let atk = self.attack.len(); + let atkdcy = atk + self.decay.len(); + + self.index += 1; + + if idx < self.len() { + let val = if idx < atk { + self.attack[idx] + } else if idx >= atk && idx < atkdcy { + self.decay[idx - atk] + } else { + self.release[idx - atkdcy] + }; + + Some(val) + } else { + None + } + } +} + fn interpolate(start: Amplitude, end: Amplitude, milliseconds: Millisecond) -> Vec<Amplitude> { let step_size = (end - start) / milliseconds as f32; let mut amps = vec!(); diff --git a/klangfarbrs/src/lib.rs b/klangfarbrs/src/lib.rs index 8bd1e50..fc5e6f9 100644 --- a/klangfarbrs/src/lib.rs +++ b/klangfarbrs/src/lib.rs @@ -17,8 +17,8 @@ mod phasor; mod osc; use osc::{Osc, Waveform}; -pub mod adsr; -use adsr::Envelope; +pub mod envelope; +use envelope::Envelope; /// Aliasing some types to distinguish various audio properties. type Sample = f32; @@ -47,7 +47,6 @@ pub struct MonoSynth { pub fm_frequency: Hz, pub fm_depth: Amplitude, fm_osc: Osc, - current_envelope_position: usize, } #[methods] @@ -72,13 +71,12 @@ impl MonoSynth { phasor_bend: Vector2::new(0.0, 0.0), continuous: true, duration: 0, - envelope: Envelope::new(500, 1000, 0.5, 4000, sprt), + envelope: Envelope::new(30, 500, 0.5, 1000, sprt), cutoff: 0.0, frequency_modulation: false, fm_frequency: 10.0, fm_depth: 0.1, fm_osc: Osc::new(freq * 2.0, sprt), - current_envelope_position: 0, } } @@ -167,6 +165,11 @@ impl MonoSynth { } #[export] + fn trigger(&mut self, _owner: &Node) { + self.envelope.index = 0; + } + + #[export] pub fn frames(&mut self, _owner: &Node, samples: i32) -> TypedArray<Vector2> { let mut frames = TypedArray::new(); @@ -189,22 +192,9 @@ impl MonoSynth { // } if !self.continuous { - let pos = self.current_envelope_position; - let atk = self.envelope.attack.len(); - let atkdcy = atk + self.envelope.decay.len(); - - if pos < atk { - sample = sample * self.envelope.attack[pos] - } else if pos >= atk && pos < atkdcy { - sample = sample * self.envelope.decay[pos - atk] - } else if pos < self.envelope.len() { - sample = sample * self.envelope.release[pos - atkdcy] - } - - self.current_envelope_position += 1; - - if self.current_envelope_position >= self.envelope.len() { - self.current_envelope_position = 0; + sample *= match self.envelope.next() { + Some(a) => a, + None => 0.0, } } |