Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "textstep"
version = "1.2.3"
version = "1.2.4"
edition = "2024"

[dependencies]
Expand Down
325 changes: 324 additions & 1 deletion src/presets/synth_presets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const fn sp(
}
}

/// Override LFO settings on a preset
/// Override LFO1 settings on a preset
const fn with_lfo(mut p: SynthParams, wave: u8, div: f32, depth: f32, dest: u8) -> SynthParams {
p.lfo_waveform = wave;
p.lfo_division = div;
Expand All @@ -39,6 +39,31 @@ const fn with_lfo(mut p: SynthParams, wave: u8, div: f32, depth: f32, dest: u8)
p
}

/// Override LFO2 settings on a preset
const fn with_lfo2(mut p: SynthParams, wave: u8, div: f32, depth: f32, dest: u8) -> SynthParams {
p.lfo2_waveform = wave;
p.lfo2_division = div;
p.lfo2_depth = depth;
p.lfo2_dest = dest;
p
}

/// Override both LFO1 and LFO2 settings
const fn with_lfos(
p: SynthParams,
w1: u8, d1: f32, dp1: f32, dst1: u8,
w2: u8, d2: f32, dp2: f32, dst2: u8,
) -> SynthParams {
with_lfo2(with_lfo(p, w1, d1, dp1, dst1), w2, d2, dp2, dst2)
}

/// Override send effects on a preset
const fn with_sends(mut p: SynthParams, reverb: f32, delay: f32) -> SynthParams {
p.send_reverb = reverb;
p.send_delay = delay;
p
}

pub static SYNTH_PRESETS: &[SynthSoundPreset] = &[
// ── Bass ─────────────────────────────────────────────────────────────
SynthSoundPreset {
Expand Down Expand Up @@ -102,6 +127,46 @@ pub static SYNTH_PRESETS: &[SynthSoundPreset] = &[
0.80),
1, 0.47, 0.3, 3), // LFO: Tri, 1/4, moderate, → Osc1 PWM
},
SynthSoundPreset {
name: "Growl Bass", category: "Bass",
// Saw + sub, LFO1 wobbles filter, LFO2 pumps osc2 level rhythmically
params: with_lfos(sp(1, 0.5, 0.0, 0.9,
1, 0.5, 0.0, 0.5, 0.54,
0.6,
0.01, 0.2, 0.9, 0.1,
0.01, 0.2, 0.9, 0.1,
0, 0.35, 0.45, 0.15,
0.0, 0.25, 0.2, 0.1,
0.80),
1, 0.22, 0.40, 0, // LFO1: Tri, 1/8, strong → Filter
4, 0.35, 0.30, 7), // LFO2: Square, 1/4T, moderate → Osc2 Level
},
SynthSoundPreset {
name: "Rubber Bass", category: "Bass",
// Sine + detuned saw, LFO1 slow pitch drift, LFO2 on filter
params: with_lfos(sp(2, 0.5, 0.0, 0.8,
1, 0.5, 0.0, 0.6, 0.53,
0.5,
0.01, 0.15, 0.85, 0.12,
0.01, 0.15, 0.85, 0.12,
0, 0.38, 0.25, 0.10,
0.0, 0.3, 0.2, 0.15,
0.78),
0, 0.67, 0.06, 2, // LFO1: Sine, 1 bar, subtle → Osc1 Pitch
1, 0.47, 0.20, 0), // LFO2: Tri, 1/4, moderate → Filter
},
SynthSoundPreset {
name: "FM Bass", category: "Bass",
// Square + sine octave up, snappy filter env
params: sp(0, 0.5, 0.5, 0.7,
2, 0.75, 0.0, 0.5, 0.5, // Sine +12
0.4,
0.00, 0.12, 0.6, 0.08,
0.00, 0.12, 0.6, 0.08,
0, 0.30, 0.35, 0.50, // LP, low cutoff, reso, strong env
0.0, 0.10, 0.0, 0.06,
0.82),
},

// ── Lead ─────────────────────────────────────────────────────────────
SynthSoundPreset {
Expand Down Expand Up @@ -141,6 +206,34 @@ pub static SYNTH_PRESETS: &[SynthSoundPreset] = &[
0.70),
0, 0.35, 0.12, 2), // LFO: Sine, moderate rate, vibrato, → Osc1 Tune
},
SynthSoundPreset {
name: "Trance Lead", category: "Lead",
// Bright saw, LFO1 on PWM, LFO2 slow filter sweep for movement
params: with_lfos(sp(1, 0.5, 0.0, 0.9,
0, 0.5, 0.4, 0.5, 0.52,
0.0,
0.03, 0.2, 0.85, 0.35,
0.03, 0.2, 0.85, 0.35,
0, 0.60, 0.30, 0.20,
0.01, 0.3, 0.4, 0.3,
0.72),
1, 0.47, 0.25, 3, // LFO1: Tri, 1/4, moderate → Osc1 PWM
0, 0.78, 0.15, 0), // LFO2: Sine, 2 bars, gentle → Filter
},
SynthSoundPreset {
name: "Portamento Lead", category: "Lead",
// Single saw, no osc2, vibrato + filter motion
params: with_lfos(sp(1, 0.5, 0.0, 1.0,
2, 0.5, 0.0, 0.0, 0.5, // Osc2 off
0.2,
0.04, 0.2, 0.9, 0.4,
0.04, 0.2, 0.9, 0.4,
0, 0.55, 0.20, 0.18,
0.02, 0.3, 0.3, 0.3,
0.78),
0, 0.35, 0.10, 2, // LFO1: Sine, 1/4T, vibrato → Pitch
1, 0.67, 0.12, 0), // LFO2: Tri, 1 bar, subtle → Filter
},

// ── Pad ──────────────────────────────────────────────────────────────
SynthSoundPreset {
Expand Down Expand Up @@ -195,6 +288,34 @@ pub static SYNTH_PRESETS: &[SynthSoundPreset] = &[
0.60),
0, 0.88, 0.18, 0), // LFO: Sine, 4 bars, gentle, → Filter
},
SynthSoundPreset {
name: "Shimmer Pad", category: "Pad",
// Sines detuned, LFO1 slow filter, LFO2 slow detune drift
params: with_lfos(with_sends(sp(2, 0.5, 0.0, 0.6,
2, 0.5, 0.0, 0.5, 0.53,
0.2,
0.50, 0.2, 0.85, 0.60,
0.50, 0.2, 0.85, 0.60,
0, 0.55, 0.20, 0.10,
0.4, 0.6, 0.3, 0.5,
0.62), 0.35, 0.15),
0, 0.88, 0.12, 0, // LFO1: Sine, 4 bars, subtle → Filter
1, 0.78, 0.08, 8), // LFO2: Tri, 2 bars, gentle → Osc2 Detune
},
SynthSoundPreset {
name: "Evolving Pad", category: "Pad",
// Squares with PWM, LFO1 on PWM1, LFO2 on PWM2 at different rates
params: with_lfos(with_sends(sp(0, 0.5, 0.4, 0.6,
0, 0.5, 0.6, 0.5, 0.52,
0.3,
0.45, 0.3, 0.75, 0.55,
0.45, 0.3, 0.75, 0.55,
0, 0.42, 0.15, 0.08,
0.3, 0.5, 0.3, 0.4,
0.65), 0.30, 0.10),
1, 0.67, 0.30, 3, // LFO1: Tri, 1 bar, strong → Osc1 PWM
1, 0.78, 0.25, 6), // LFO2: Tri, 2 bars, moderate → Osc2 PWM
},

// ── Pluck ────────────────────────────────────────────────────────────
SynthSoundPreset {
Expand Down Expand Up @@ -231,6 +352,31 @@ pub static SYNTH_PRESETS: &[SynthSoundPreset] = &[
0.80),
},

SynthSoundPreset {
name: "Kalimba", category: "Pluck",
// Sine + sine octave, very short decay, gentle filter env
params: sp(2, 0.5, 0.0, 0.8,
2, 0.75, 0.0, 0.4, 0.5, // Sine +12
0.0,
0.00, 0.18, 0.0, 0.08,
0.00, 0.10, 0.0, 0.06,
0, 0.65, 0.08, 0.35,
0.0, 0.12, 0.0, 0.08,
0.78),
},
SynthSoundPreset {
name: "Harp", category: "Pluck",
// Saw + sine, moderate decay, open filter
params: with_sends(sp(1, 0.5, 0.0, 0.6,
2, 0.5, 0.0, 0.5, 0.51,
0.0,
0.00, 0.35, 0.0, 0.25,
0.00, 0.25, 0.0, 0.20,
0, 0.60, 0.12, 0.40,
0.0, 0.25, 0.0, 0.2,
0.72), 0.30, 0.15),
},

// ── Stab ─────────────────────────────────────────────────────────────
SynthSoundPreset {
name: "Chord Stab", category: "Stab",
Expand All @@ -255,6 +401,31 @@ pub static SYNTH_PRESETS: &[SynthSoundPreset] = &[
0.75),
},

SynthSoundPreset {
name: "Detroit Stab", category: "Stab",
// Single saw, fast filter env snap
params: sp(1, 0.5, 0.0, 0.9,
1, 0.5, 0.0, 0.0, 0.5,
0.2,
0.00, 0.08, 0.0, 0.06,
0.00, 0.08, 0.0, 0.06,
0, 0.30, 0.20, 0.70, // LP, low cut, strong env
0.0, 0.06, 0.0, 0.04,
0.82),
},
SynthSoundPreset {
name: "Brass Stab", category: "Stab",
// Two saws, medium attack for brass-like onset
params: sp(1, 0.5, 0.0, 0.8,
1, 0.5, 0.0, 0.7, 0.53,
0.3,
0.06, 0.12, 0.5, 0.12,
0.06, 0.12, 0.5, 0.12,
0, 0.45, 0.15, 0.35,
0.04, 0.10, 0.2, 0.1,
0.78),
},

// ── Keys ─────────────────────────────────────────────────────────────
SynthSoundPreset {
name: "Electric Piano", category: "Keys",
Expand Down Expand Up @@ -292,6 +463,118 @@ pub static SYNTH_PRESETS: &[SynthSoundPreset] = &[
0.80),
},

SynthSoundPreset {
name: "Wurlitzer", category: "Keys",
// Sine with tremolo (LFO1→Volume) and gentle filter env
params: with_lfo(sp(2, 0.5, 0.0, 0.8,
2, 0.75, 0.0, 0.2, 0.5, // Sine +12, subtle
0.0,
0.01, 0.35, 0.55, 0.25,
0.01, 0.20, 0.3, 0.15,
0, 0.50, 0.12, 0.20,
0.0, 0.25, 0.15, 0.2,
0.72),
0, 0.47, 0.10, 10), // LFO: Sine, 1/4, tremolo → Volume
},
SynthSoundPreset {
name: "Toy Piano", category: "Keys",
// Square, short decay, bright, no filter env
params: sp(0, 0.5, 0.5, 0.8,
2, 0.75, 0.0, 0.3, 0.5,
0.0,
0.00, 0.20, 0.0, 0.10,
0.00, 0.12, 0.0, 0.08,
0, 0.70, 0.05, 0.20,
0.0, 0.10, 0.0, 0.08,
0.75),
},

// ── Drums (synth-based percussion) ─────────────────────────────────
SynthSoundPreset {
name: "Synth Kick", category: "Drums",
// Sine with fast pitch drop (sweep), no sustain, punchy
params: sp(2, 0.25, 0.0, 1.0, // Sine, low tune
2, 0.5, 0.0, 0.0, 0.5, // Osc2 off
0.7, // Heavy sub
0.00, 0.15, 0.0, 0.02, // Very short envelope
0.00, 0.08, 0.0, 0.02,
0, 0.45, 0.0, 0.30, // LP, moderate, some env
0.0, 0.06, 0.0, 0.02,
0.90),
},
SynthSoundPreset {
name: "808 Kick", category: "Drums",
// Long sine sub with pitch sweep
params: sp(2, 0.20, 0.0, 1.0,
2, 0.5, 0.0, 0.0, 0.5,
0.8,
0.00, 0.40, 0.0, 0.05, // Medium-long decay
0.00, 0.25, 0.0, 0.05,
0, 0.35, 0.0, 0.15,
0.0, 0.10, 0.0, 0.03,
0.88),
},
SynthSoundPreset {
name: "Synth Snare", category: "Drums",
// Noise + sine body, short decay
params: sp(2, 0.45, 0.0, 0.6, // Sine body
3, 0.5, 0.5, 0.7, 0.5, // Noise layer
0.0,
0.00, 0.12, 0.0, 0.04,
0.00, 0.08, 0.0, 0.03,
0, 0.55, 0.15, 0.45, // LP, moderate env
0.0, 0.08, 0.0, 0.03,
0.82),
},
SynthSoundPreset {
name: "Noise Snare", category: "Drums",
// Pure noise, tight filter env for snap
params: sp(3, 0.5, 0.5, 0.9,
3, 0.5, 0.3, 0.3, 0.5,
0.0,
0.00, 0.10, 0.0, 0.03,
0.00, 0.06, 0.0, 0.02,
0, 0.40, 0.30, 0.60,
0.0, 0.06, 0.0, 0.02,
0.80),
},
SynthSoundPreset {
name: "Synth Tom", category: "Drums",
// Sine with pitch sweep, medium decay
params: sp(2, 0.40, 0.0, 0.9,
2, 0.5, 0.0, 0.0, 0.5,
0.3,
0.00, 0.22, 0.0, 0.05,
0.00, 0.15, 0.0, 0.04,
0, 0.50, 0.10, 0.25,
0.0, 0.10, 0.0, 0.04,
0.80),
},
SynthSoundPreset {
name: "Zap", category: "Drums",
// Fast pitch sweep down, very short — like a 909 zap
params: sp(2, 0.55, 0.0, 1.0,
2, 0.5, 0.0, 0.0, 0.5,
0.0,
0.00, 0.06, 0.0, 0.02,
0.00, 0.04, 0.0, 0.01,
0, 0.70, 0.0, 0.80, // Strong filter env for sweep
0.0, 0.04, 0.0, 0.01,
0.78),
},
SynthSoundPreset {
name: "Clap", category: "Drums",
// Noise burst, medium decay
params: sp(3, 0.5, 0.5, 0.8,
3, 0.5, 0.3, 0.4, 0.5,
0.0,
0.00, 0.15, 0.0, 0.05,
0.00, 0.10, 0.0, 0.04,
0, 0.50, 0.25, 0.40,
0.0, 0.08, 0.0, 0.04,
0.75),
},

// ── FX ───────────────────────────────────────────────────────────────
SynthSoundPreset {
name: "Noise Sweep", category: "FX",
Expand Down Expand Up @@ -328,6 +611,46 @@ pub static SYNTH_PRESETS: &[SynthSoundPreset] = &[
0.55),
0, 0.78, 0.25, 0), // LFO: Sine, 2 bars, moderate, → Filter
},
SynthSoundPreset {
name: "Siren", category: "FX",
// Sine, fast LFO1 on pitch, LFO2 on filter for texture
params: with_lfos(sp(2, 0.5, 0.0, 0.9,
2, 0.5, 0.0, 0.0, 0.5,
0.0,
0.01, 0.1, 1.0, 0.3,
0.01, 0.1, 1.0, 0.3,
0, 0.60, 0.10, 0.0,
0.0, 0.1, 0.0, 0.1,
0.70),
0, 0.10, 0.35, 2, // LFO1: Sine, 1/16, strong → Pitch
1, 0.47, 0.20, 0), // LFO2: Tri, 1/4, moderate → Filter
},
SynthSoundPreset {
name: "Riser", category: "FX",
// Noise, long attack envelope, building tension
params: sp(3, 0.5, 0.5, 0.7,
3, 0.5, 0.3, 0.4, 0.5,
0.0,
0.90, 0.1, 0.8, 0.30, // Very long attack
0.90, 0.1, 0.8, 0.30,
0, 0.25, 0.35, 0.50, // LP, low cut, opens with env
0.80, 0.2, 0.6, 0.3, // Filter env also long attack
0.65),
},
SynthSoundPreset {
name: "Robot", category: "FX",
// Square, LFO1 fast on pitch (ring mod effect), LFO2 on volume (tremolo)
params: with_lfos(sp(0, 0.5, 0.5, 0.8,
0, 0.75, 0.5, 0.4, 0.5,
0.0,
0.01, 0.1, 0.8, 0.1,
0.01, 0.1, 0.8, 0.1,
0, 0.50, 0.15, 0.0,
0.0, 0.1, 0.0, 0.05,
0.70),
0, 0.05, 0.20, 2, // LFO1: Sine, 1/16D, fast pitch → ring mod
4, 0.22, 0.40, 10), // LFO2: Square, 1/8, strong tremolo → Volume
},
];

pub fn categories() -> Vec<&'static str> {
Expand Down
Loading
Loading