From 22cb7d7cbcacbfe3a7d3a2d454e6b8cf49ae989c Mon Sep 17 00:00:00 2001 From: Graham Northup Date: Fri, 13 Oct 2017 12:54:04 -0400 Subject: Added LUTs and ControlRate; improved parser --- src/synth/adsr.rs | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/synth/adsr.rs (limited to 'src/synth/adsr.rs') diff --git a/src/synth/adsr.rs b/src/synth/adsr.rs new file mode 100644 index 0000000..ca7be9c --- /dev/null +++ b/src/synth/adsr.rs @@ -0,0 +1,122 @@ +use super::*; + +#[derive(Debug,Clone,Copy,PartialEq,Eq)] +pub enum Phase { + Delay, + Attack, + Hold, + Decay, + Sustain, + Release, +} + +#[derive(Debug)] +pub struct DAHDSR { + pub delay: GenBox, + pub attack: GenBox, + pub hold: GenBox, + pub decay: GenBox, + pub sustain: GenBox, + pub release: GenBox, + pub gate: GenBox, + pub phase: Phase, + pub cur: f32, + pub attack_cd: f32, + pub decay_cd: f32, + pub buf: SampleBuffer, +} + +impl Generator for DAHDSR { + fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer { + self.buf.rate = Rate::Sample; + + let delay = self.delay.eval(params).first(); + let attack = self.attack.eval(params).first(); + let hold = self.attack.eval(params).first(); + let decay = self.decay.eval(params).first(); + let sustain = self.sustain.eval(params).first(); + let release = self.release.eval(params).first(); + let gate = self.gate.eval(params).first(); + + if gate >= 0.5 { + if self.phase == Phase::Release { + self.phase = Phase::Delay; + self.attack_cd = delay; + self.cur = 0.0; + } + } else{ + self.phase = Phase::Release; + } + + for samp in self.buf.samples.iter_mut() { + match self.phase { + Phase::Delay => { + self.attack_cd -= 1.0; + if self.attack_cd <= 0.0 { + self.phase = Phase::Attack; + } + }, + Phase::Attack => { + self.cur += attack; + if self.cur >= 1.0 { + self.cur = 1.0; + self.phase = Phase::Hold; + self.decay_cd = hold; + } + }, + Phase::Hold => { + self.decay_cd -= 1.0; + if self.decay_cd <= 0.0 { + self.phase = Phase::Decay; + } + }, + Phase::Decay => { + self.cur -= decay; + if self.cur <= sustain { + self.cur = sustain; + self.phase = Phase::Sustain; + } + }, + Phase::Sustain => { + self.cur = sustain; + }, + Phase::Release => { + self.cur -= release; + if self.cur < 0.0 { + self.cur = 0.0; + } + }, + } + *samp = self.cur; + } + + &self.buf + } + fn buffer(&self) -> &SampleBuffer { &self.buf } + fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer { + mem::replace(&mut self.buf, buf) + } +} + +pub struct DAHDSRFactory; + +impl GeneratorFactory for DAHDSRFactory { + fn new(&self, params: &mut FactoryParameters) -> Result { + Ok(Box::new(DAHDSR { + delay: params.remove_param("delay", 1)?.into_gen()?, + attack: params.remove_param("attack", 2)?.into_gen()?, + hold: params.remove_param("hold", 3)?.into_gen()?, + decay: params.remove_param("decay", 4)?.into_gen()?, + sustain: params.remove_param("sustain", 5)?.into_gen()?, + release: params.remove_param("release", 6)?.into_gen()?, + gate: params.remove_param("gate", 0)?.into_gen()?, + phase: Phase::Release, + cur: 0.0, + attack_cd: 0.0, + decay_cd: 0.0, + buf: SampleBuffer::new(params.env.default_buffer_size), + })) + } +} + +pub static Factory: DAHDSRFactory = DAHDSRFactory; -- cgit v1.2.3-70-g09d2