Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::dsp::Voice;

mod app;
mod dsp;
mod modulation;

const APP_NAME: &str = "Ichiro";

Expand Down Expand Up @@ -155,7 +156,7 @@ fn main() -> Result<(), anyhow::Error> {
Box::new(|cc| {
Box::new(SynthApp::new(cc, cancel_rx, state_tx, plot_rx))
}),
);
).expect("TODO: panic message");

Ok(())
}
119 changes: 87 additions & 32 deletions src/modulation.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1,91 @@
const SUSTAIN_LEVEL_DEFAULT: Output = 1.0,
const ATTACK_DEFAULT: usize = 10,
const DECAY_DEFAULT: usize = 10,
const RELEASE_DEFAULT: usize = 10,
type Samples: isize;

enum AdsrEnvelopeState {
Attack(remanining: usize),
Decay(remaining: usize),
Sustain(level: f32,),
Release(remaining: usize,),
use std::ops::Mul;

#[derive(Copy, Clone)]
struct Samples(isize);

const SUSTAIN_LEVEL_DEFAULT: Sample = Sample(1.0);
const ATTACK_DEFAULT: Samples = Samples(10);
const DECAY_DEFAULT: Samples = Samples(10);
const RELEASE_DEFAULT: Samples = Samples(10);

#[derive(Copy, Clone)]
enum EnvelopePhase {
Attack{remaining: Samples},
Decay{remaining: Samples},
Sustain{level: Sample },
Release{remaining: Samples},
Off,
}


#[derive(Copy, Clone)]
struct AdsrEnvelope {
state: AdsrEnvelopeState,
sustain_level: TickResult,
level: Sample,
phase: EnvelopePhase,
sustain_level: Sample,
attack: Samples,
decay: Samples,
release: Samples,
}

type Output = f32;
impl Default for AdsrEnvelope {
fn default() -> Self {
AdsrEnvelope {
phase: EnvelopePhase::Off,
sustain_level: Samples(SUSTAIN_LEVEL_DEFAULT),
attack: Samples(ATTACK_DEFAULT),
decay: Samples(DECAY_DEFAULT),
release: Samples(RELEASE_DEFAULT),
}
}
}

#[derive(Default, Copy, Clone)]
struct Sample(f32);
impl Into<Sample> for f32 {
fn into(self) -> Sample {
Sample(self)
}
}

enum Event {
NoteOn,
NoteOff,
}

impl Mul for Sample {
type Output = Sample;

fn mul(self, rhs: Self) -> Self::Output {
Sample(self.0 * rhs.0)
}
}

impl AdsrEnvelope {
fn new() -> Self {
Self {
state: AdsrEnvelopeState::Off,
phase: EnvelopePhase::Off,
sustain_level: SUSTAIN_LEVEL_DEFAULT,
attack: ATTACK_DEFAULT,
decay: DECAY_DEFAULT,
release: RELEASE_DEFAULT,
}
}

fn tick() -> Output {
fn tick() {
// TODO! progress state!
self.state = match self.state {
AdsrEnvelopeState::Attack => ,
Decay =>,
Sustain(n) => Sustain
Off => Off,
EnvelopePhase::Attack => EnvelopePhase::Off,
Decay => EnvelopePhase::Off,
Sustain(n) => EnvelopePhase::Off,
Off => EnvelopePhase::Off,
}
}

fn process_event(&mut self, event: Event) {
match event {
Event::NoteOn => self.note_on(),
Event::NoteOff => self.note_off(),
}
}

Expand All @@ -50,32 +96,41 @@ impl AdsrEnvelope {
// Should it? (re-trigger)
fn note_off(&mut self) {
// Refactor -> implement state machine on the state enum
self.state = match self.state {
Self::Off { _ } =>
_ => u:qnimplemented!()
self.phase = match self.phase {
EnvelopePhase::Off => EnvelopePhase::Off,
_ => unimplemented!()
};
}

fn note_on(&mut self) {
match self.state {
_ => unimplemented!()
};
self.phase = match self.phase {
EnvelopePhase::Off => EnvelopePhase::Attack {remaining: self.attack},
EnvelopePhase::Attack {}
}
}

fn change_attack(&mut self, attack: Sample) {
fn change_attack(&mut self, attack: Samples) {
self.attack = attack;
}

fn change_decay(&mut self, decay: Sample) {
fn change_decay(&mut self, decay: Samples) {
self.decay = decay;
}

fn change_sustain(&mut self, sustain: f32) {
self.sustain = sustain;
fn change_sustain(&mut self, sustain_level: Sample) {
self.sustain_level = sustain_level;
}

fn vca() -> f32 {
0f32
fn change_release(&mut self, release: Samples) {
self.release = release;
}

fn reset(&mut self) {
*self = AdsrEnvelope::default();
}

fn vca(&self, input: Sample) -> Sample {
input * self.level
}
}

Loading