use tunes::prelude::*;
fn main() -> anyhow::Result<()> {
println!("\n🌊 Example: LFO Modulation\n");
let engine = AudioEngine::new()?;
let mut comp = Composition::new(Tempo::new(120.0));
comp.track("wobble_bass")
.waveform(Waveform::Sawtooth)
.filter(Filter::low_pass(800.0, 0.6))
.modulate(ModRoute::new(
LFO::new(Waveform::Sine, 2.0, 1.0), ModTarget::FilterCutoff,
0.8, ))
.at(0.0)
.notes(&[C2, C2, C2, C2], 0.5);
comp.instrument("vibrato", &Instrument::bright_lead())
.modulate(ModRoute::new(
LFO::fast_sine(0.5), ModTarget::Pitch,
0.3, ))
.at(2.5)
.notes(&[E4, F4, G4, A4], 0.8);
comp.instrument("tremolo", &Instrument::organ())
.modulate(ModRoute::new(
LFO::new(Waveform::Sine, 6.0, 1.0),
ModTarget::Volume,
0.7, ))
.at(6.0)
.note(&[C4, E4, G4], 2.0);
comp.instrument("auto_pan", &Instrument::synth_lead())
.modulate(ModRoute::new(
LFO::slow_sine(1.0),
ModTarget::Pan,
1.0, ))
.at(8.5)
.notes(&[C4, D4, E4, F4, G4, F4, E4, D4], 0.25);
comp.track("filter_sweep")
.waveform(Waveform::Square)
.filter(Filter::low_pass(400.0, 0.7))
.modulate(ModRoute::new(
LFO::triangle(0.5, 1.0), ModTarget::FilterCutoff,
1.0,
))
.at(11.0)
.notes(&[A2, A2, A2, A2], 0.8);
comp.track("stepped_filter")
.waveform(Waveform::Sawtooth)
.filter(Filter::low_pass(600.0, 0.5))
.modulate(ModRoute::new(
LFO::square(4.0, 1.0), ModTarget::FilterCutoff,
0.7,
))
.at(14.5)
.notes(&[E3, E3, E3, E3, E3, E3, E3, E3], 0.25);
comp.track("fast_wobble")
.waveform(Waveform::Sawtooth)
.filter(Filter::low_pass(1000.0, 0.8))
.modulate(ModRoute::new(
LFO::new(Waveform::Sine, 8.0, 1.0), ModTarget::FilterCutoff,
0.9,
))
.at(17.0)
.notes(&[D2, D2, D2, D2], 0.5);
comp.track("multi_mod")
.waveform(Waveform::Sawtooth)
.filter(Filter::low_pass(800.0, 0.5))
.modulate(ModRoute::new(
LFO::new(Waveform::Sine, 2.0, 0.8),
ModTarget::FilterCutoff,
0.6,
))
.modulate(ModRoute::new(
LFO::new(Waveform::Sine, 5.0, 0.5),
ModTarget::Pitch,
0.2, ))
.at(19.5)
.notes(&[G3, G3, G3, G3], 0.5);
comp.track("resonance_mod")
.waveform(Waveform::Square)
.filter(Filter::low_pass(1200.0, 0.3))
.modulate(ModRoute::new(
LFO::new(Waveform::Sine, 1.5, 1.0),
ModTarget::FilterResonance,
0.7,
))
.at(22.0)
.notes(&[C3, E3, G3, C4], 0.8);
comp.track("evolving_pad")
.waveform(Waveform::Sawtooth)
.filter(Filter::low_pass(600.0, 0.4))
.modulate(ModRoute::new(
LFO::new(Waveform::Triangle, 0.3, 1.0), ModTarget::FilterCutoff,
0.5,
))
.at(25.5)
.note(&[C3, E3, G3, B3], 4.0);
println!("✓ LFO (Low Frequency Oscillator):");
println!(" - Periodically modulates parameters over time");
println!(" - Frequency: typically 0.1 to 20 Hz");
println!("\n✓ Modulation targets:");
println!(" - ModTarget::FilterCutoff - Wah/wobble effects");
println!(" - ModTarget::FilterResonance - Resonance sweeps");
println!(" - ModTarget::Volume - Tremolo effect");
println!(" - ModTarget::Pitch - Vibrato effect");
println!(" - ModTarget::Pan - Auto-pan/stereo movement");
println!("\n✓ LFO waveforms:");
println!(" - Sine: Smooth, natural modulation");
println!(" - Triangle: Linear back-and-forth");
println!(" - Square: Stepped/rhythmic changes");
println!(" - Sawtooth: Ramp up or down");
println!("\n✓ Usage:");
println!(" .modulate(ModRoute::new(");
println!(" LFO::new(Waveform::Sine, frequency, depth),");
println!(" ModTarget::FilterCutoff,");
println!(" amount");
println!(" ))");
println!("\n✓ Presets:");
println!(" - LFO::slow_sine(depth) - 0.5 Hz sine");
println!(" - LFO::fast_sine(depth) - 5 Hz sine (vibrato)");
println!(" - LFO::triangle(freq, depth) - Triangle wave");
println!(" - LFO::square(freq, depth) - Square wave\\n");
engine.play_mixer(&comp.into_mixer())?;
Ok(())
}