use super::{
Adsr, DriveShape, KitStyle, Mode, NoiseColor, SeqNote, SeqWave, SuperWave, Track, Value,
default_gain,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
fn default_duty() -> Value {
Value::Const(0.5)
}
fn default_q() -> f32 {
0.707
}
fn default_steps_per_beat() -> u32 {
4
}
fn default_mod_depth() -> f32 {
0.5
}
fn default_mod_mix() -> f32 {
0.5
}
fn default_chorus_rate() -> f32 {
1.5
}
fn default_flanger_rate() -> f32 {
0.25
}
fn default_flanger_feedback() -> f32 {
0.5
}
fn default_phaser_rate() -> f32 {
0.4
}
fn default_phaser_feedback() -> f32 {
0.3
}
fn default_comp_attack() -> f32 {
0.005
}
fn default_comp_release() -> f32 {
0.08
}
fn default_voices() -> u32 {
7
}
fn default_detune() -> f32 {
15.0
}
fn default_seq_fm_ratio() -> f32 {
1.0
}
fn default_seq_fm_index() -> f32 {
5.0
}
fn default_seq_fm_strike() -> f32 {
0.2
}
fn default_pluck_decay() -> f32 {
0.996
}
fn default_pluck_body() -> f32 {
0.0
}
fn default_pluck_pick() -> f32 {
0.0
}
fn default_pluck_tone() -> f32 {
0.0
}
fn default_piano_hammer() -> f32 {
1.0
}
fn default_piano_strike() -> f32 {
0.125
}
fn default_piano_inharm() -> f32 {
1.0
}
fn default_piano_detune() -> f32 {
1.0
}
fn default_piano_decay() -> f32 {
1.0
}
fn default_bass_cutoff() -> f32 {
250.0
}
fn default_bass_env() -> f32 {
700.0
}
fn default_bass_env_vel() -> f32 {
1100.0
}
fn default_bass_decay() -> f32 {
0.15
}
fn default_bass_click() -> f32 {
0.0
}
fn default_bass_body() -> f32 {
0.7
}
fn default_bass_sub() -> f32 {
0.45
}
fn default_bass_sub_ratio() -> f32 {
1.0
}
fn default_bass_drive() -> f32 {
0.0
}
fn default_bass_body_decay() -> f32 {
2.0
}
fn default_duck_amount() -> f32 {
0.8
}
fn default_duck_attack() -> f32 {
0.005
}
fn default_duck_release() -> f32 {
0.25
}
fn default_modal_mix() -> f32 {
1.0
}
fn default_impact_hardness() -> f32 {
0.5
}
fn default_dust_decay() -> f32 {
0.02
}
#[non_exhaustive]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum Node {
Square {
freq: Value,
#[serde(default = "default_duty")]
duty: Value,
},
Triangle {
freq: Value,
},
Sawtooth {
freq: Value,
},
Sine {
freq: Value,
},
Noise {
#[serde(default)]
color: NoiseColor,
},
Fm {
freq: Value,
ratio: f32,
index: Value,
},
Super {
#[serde(default)]
wave: SuperWave,
freq: Value,
#[serde(default = "default_voices")]
voices: u32,
#[serde(default = "default_detune")]
detune_cents: f32,
},
Seq {
bpm: f32,
#[serde(default = "default_steps_per_beat")]
steps_per_beat: u32,
wave: SeqWave,
#[serde(default = "default_duty")]
duty: Value,
#[serde(flatten)]
fm: FmKnobs,
#[serde(flatten)]
pluck: PluckKnobs,
#[serde(flatten)]
piano: PianoKnobs,
#[serde(default)]
kit: KitStyle,
#[serde(flatten)]
bass: BassKnobs,
#[serde(flatten)]
sf2: Sf2Knobs,
#[serde(default)]
swing: f32,
#[serde(default)]
humanize: f32,
env: Adsr,
notes: Vec<SeqNote>,
},
Impact {
#[serde(default = "default_impact_hardness")]
hardness: f32,
#[serde(default = "default_gain")]
velocity: f32,
},
Dust {
density: f32,
#[serde(default = "default_dust_decay")]
decay: f32,
},
Env {
#[serde(flatten)]
adsr: Adsr,
},
Tracks {
tracks: Vec<Track>,
#[serde(default)]
master: Vec<Node>,
},
Mix {
inputs: Vec<Node>,
},
Mul {
inputs: Vec<Node>,
},
Chain {
stages: Vec<Node>,
},
Lowpass {
cutoff: Value,
#[serde(default = "default_q")]
q: f32,
},
Highpass {
cutoff: Value,
#[serde(default = "default_q")]
q: f32,
},
Bandpass {
cutoff: Value,
#[serde(default = "default_q")]
q: f32,
},
Notch {
cutoff: Value,
#[serde(default = "default_q")]
q: f32,
},
Peak {
cutoff: Value,
#[serde(default = "default_q")]
q: f32,
#[serde(default)]
gain_db: f32,
},
Lowshelf {
cutoff: Value,
#[serde(default)]
gain_db: f32,
},
Highshelf {
cutoff: Value,
#[serde(default)]
gain_db: f32,
},
Gain {
amount: Value,
},
Bitcrush {
bits: u8,
},
Downsample {
factor: u32,
},
Delay {
secs: f32,
#[serde(default)]
feedback: f32,
},
Reverb {
#[serde(default)]
room: f32,
#[serde(default)]
mix: f32,
},
Modal {
modes: Vec<Mode>,
#[serde(default = "default_modal_mix")]
mix: f32,
},
Drive {
amount: Value,
#[serde(default)]
shape: DriveShape,
#[serde(default, skip_serializing_if = "Option::is_none")]
aa: Option<bool>,
},
RingMod {
freq: Value,
},
Flanger {
#[serde(default = "default_flanger_rate")]
rate: f32,
#[serde(default = "default_mod_depth")]
depth: f32,
#[serde(default = "default_flanger_feedback")]
feedback: f32,
#[serde(default = "default_mod_mix")]
mix: f32,
},
Phaser {
#[serde(default = "default_phaser_rate")]
rate: f32,
#[serde(default = "default_mod_depth")]
depth: f32,
#[serde(default = "default_phaser_feedback")]
feedback: f32,
#[serde(default = "default_mod_mix")]
mix: f32,
},
Chorus {
#[serde(default = "default_chorus_rate")]
rate: f32,
#[serde(default = "default_mod_depth")]
depth: f32,
#[serde(default = "default_mod_mix")]
mix: f32,
},
Duck {
trigger: Box<Node>,
#[serde(default = "default_duck_amount")]
amount: f32,
#[serde(default = "default_duck_attack")]
attack: f32,
#[serde(default = "default_duck_release")]
release: f32,
},
Compress {
threshold: f32,
ratio: f32,
#[serde(default = "default_comp_attack")]
attack: f32,
#[serde(default = "default_comp_release")]
release: f32,
#[serde(default)]
makeup: f32,
},
}
impl Node {
pub fn is_processor(&self) -> bool {
matches!(
self,
Node::Lowpass { .. }
| Node::Highpass { .. }
| Node::Bandpass { .. }
| Node::Notch { .. }
| Node::Peak { .. }
| Node::Lowshelf { .. }
| Node::Highshelf { .. }
| Node::Gain { .. }
| Node::Bitcrush { .. }
| Node::Downsample { .. }
| Node::Delay { .. }
| Node::Reverb { .. }
| Node::Modal { .. }
| Node::Drive { .. }
| Node::RingMod { .. }
| Node::Chorus { .. }
| Node::Flanger { .. }
| Node::Phaser { .. }
| Node::Compress { .. }
| Node::Duck { .. }
)
}
pub fn children(&self) -> Children<'_> {
let kind = match self {
Node::Mix { inputs } | Node::Mul { inputs } => ChildrenKind::Slice(inputs.iter()),
Node::Chain { stages } => ChildrenKind::Slice(stages.iter()),
Node::Tracks { tracks, master } => ChildrenKind::Tracks {
tracks: tracks.iter(),
master: master.iter(),
},
Node::Duck { trigger, .. } => ChildrenKind::One(Some(trigger)),
Node::Square { .. }
| Node::Triangle { .. }
| Node::Sawtooth { .. }
| Node::Sine { .. }
| Node::Noise { .. }
| Node::Fm { .. }
| Node::Super { .. }
| Node::Seq { .. }
| Node::Impact { .. }
| Node::Dust { .. }
| Node::Env { .. }
| Node::Lowpass { .. }
| Node::Highpass { .. }
| Node::Bandpass { .. }
| Node::Notch { .. }
| Node::Peak { .. }
| Node::Lowshelf { .. }
| Node::Highshelf { .. }
| Node::Gain { .. }
| Node::Bitcrush { .. }
| Node::Downsample { .. }
| Node::Delay { .. }
| Node::Reverb { .. }
| Node::Modal { .. }
| Node::Drive { .. }
| Node::RingMod { .. }
| Node::Chorus { .. }
| Node::Flanger { .. }
| Node::Phaser { .. }
| Node::Compress { .. } => ChildrenKind::None,
};
Children { kind }
}
pub fn children_mut(&mut self) -> ChildrenMut<'_> {
let kind = match self {
Node::Mix { inputs } | Node::Mul { inputs } => {
ChildrenMutKind::Slice(inputs.iter_mut())
}
Node::Chain { stages } => ChildrenMutKind::Slice(stages.iter_mut()),
Node::Tracks { tracks, master } => ChildrenMutKind::Tracks {
tracks: tracks.iter_mut(),
master: master.iter_mut(),
},
Node::Duck { trigger, .. } => ChildrenMutKind::One(Some(trigger)),
Node::Square { .. }
| Node::Triangle { .. }
| Node::Sawtooth { .. }
| Node::Sine { .. }
| Node::Noise { .. }
| Node::Fm { .. }
| Node::Super { .. }
| Node::Seq { .. }
| Node::Impact { .. }
| Node::Dust { .. }
| Node::Env { .. }
| Node::Lowpass { .. }
| Node::Highpass { .. }
| Node::Bandpass { .. }
| Node::Notch { .. }
| Node::Peak { .. }
| Node::Lowshelf { .. }
| Node::Highshelf { .. }
| Node::Gain { .. }
| Node::Bitcrush { .. }
| Node::Downsample { .. }
| Node::Delay { .. }
| Node::Reverb { .. }
| Node::Modal { .. }
| Node::Drive { .. }
| Node::RingMod { .. }
| Node::Chorus { .. }
| Node::Flanger { .. }
| Node::Phaser { .. }
| Node::Compress { .. } => ChildrenMutKind::None,
};
ChildrenMut { kind }
}
pub fn walk(&self, f: &mut impl FnMut(&Node)) {
f(self);
for c in self.children() {
c.walk(f);
}
}
pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Node)) {
f(self);
for c in self.children_mut() {
c.walk_mut(f);
}
}
}
pub struct Children<'a> {
kind: ChildrenKind<'a>,
}
enum ChildrenKind<'a> {
None,
One(Option<&'a Node>),
Slice(std::slice::Iter<'a, Node>),
Tracks {
tracks: std::slice::Iter<'a, Track>,
master: std::slice::Iter<'a, Node>,
},
}
impl<'a> Iterator for Children<'a> {
type Item = &'a Node;
fn next(&mut self) -> Option<&'a Node> {
match &mut self.kind {
ChildrenKind::None => None,
ChildrenKind::One(x) => x.take(),
ChildrenKind::Slice(it) => it.next(),
ChildrenKind::Tracks { tracks, master } => match tracks.next() {
Some(t) => Some(&t.node),
None => master.next(),
},
}
}
}
pub struct ChildrenMut<'a> {
kind: ChildrenMutKind<'a>,
}
enum ChildrenMutKind<'a> {
None,
One(Option<&'a mut Node>),
Slice(std::slice::IterMut<'a, Node>),
Tracks {
tracks: std::slice::IterMut<'a, Track>,
master: std::slice::IterMut<'a, Node>,
},
}
impl<'a> Iterator for ChildrenMut<'a> {
type Item = &'a mut Node;
fn next(&mut self) -> Option<&'a mut Node> {
match &mut self.kind {
ChildrenMutKind::None => None,
ChildrenMutKind::One(x) => x.take(),
ChildrenMutKind::Slice(it) => it.next(),
ChildrenMutKind::Tracks { tracks, master } => match tracks.next() {
Some(t) => Some(&mut t.node),
None => master.next(),
},
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
pub struct FmKnobs {
#[serde(default = "default_seq_fm_ratio")]
pub fm_ratio: f32,
#[serde(default = "default_seq_fm_index")]
pub fm_index: f32,
#[serde(default = "default_seq_fm_strike")]
pub fm_strike: f32,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
pub struct PluckKnobs {
#[serde(default = "default_pluck_decay")]
pub pluck_decay: f32,
#[serde(default = "default_pluck_body")]
pub pluck_body: f32,
#[serde(default = "default_pluck_pick")]
pub pluck_pick: f32,
#[serde(default = "default_pluck_tone")]
pub pluck_tone: f32,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
pub struct PianoKnobs {
#[serde(default = "default_piano_hammer")]
pub piano_hammer: f32,
#[serde(default = "default_piano_strike")]
pub piano_strike: f32,
#[serde(default = "default_piano_inharm")]
pub piano_inharm: f32,
#[serde(default = "default_piano_detune")]
pub piano_detune: f32,
#[serde(default = "default_piano_decay")]
pub piano_decay: f32,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
pub struct BassKnobs {
#[serde(default = "default_bass_cutoff")]
pub bass_cutoff: f32,
#[serde(default = "default_bass_env")]
pub bass_env: f32,
#[serde(default = "default_bass_env_vel")]
pub bass_env_vel: f32,
#[serde(default = "default_bass_decay")]
pub bass_decay: f32,
#[serde(default = "default_bass_click")]
pub bass_click: f32,
#[serde(default = "default_bass_body")]
pub bass_body: f32,
#[serde(default = "default_bass_sub")]
pub bass_sub: f32,
#[serde(default = "default_bass_sub_ratio")]
pub bass_sub_ratio: f32,
#[serde(default = "default_bass_drive")]
pub bass_drive: f32,
#[serde(default = "default_bass_body_decay")]
pub bass_body_decay: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct Sf2Knobs {
#[serde(default)]
pub sf2: String,
#[serde(default)]
pub sf2_preset: u32,
#[serde(default)]
pub sf2_bank: u32,
}