use tunes::prelude::*;
fn main() -> anyhow::Result<()> {
println!("🎛️ Audio Effects Showcase\n");
println!("Demonstrating all available audio effects and combinations.\n");
let mut comp = Composition::new(Tempo::new(120.0));
println!("1. Core Effects - Delay, Reverb, Distortion");
comp.track("clean").at(0.0).notes(&[C4, E4, G4], 0.5);
comp.track("delay_demo")
.delay(Delay::new(0.3, 0.4, 0.5)) .at(2.0)
.notes(&[C4, E4, G4], 0.5);
comp.track("reverb_demo")
.reverb(Reverb::new(0.5, 0.5, 0.3)) .at(4.0)
.notes(&[C4, E4, G4], 0.5);
comp.track("distortion_demo")
.distortion(Distortion::new(3.0, 0.7)) .at(6.0)
.notes(&[C4, E4, G4], 0.5);
println!("\n2. Dynamic Effects - Compressor, Saturation, EQ");
comp.instrument("compressor_demo", &Instrument::synth_lead())
.compressor(Compressor::new(0.3, 4.0, 0.01, 0.1, 1.5)) .at(8.5)
.drum_grid(8, 0.2, |g| g
.sound(DrumType::Kick, &[0, 4])
.sound(DrumType::Snare, &[2, 6])
.sound(DrumType::HiHatClosed, &[0, 1, 2, 3, 4, 5, 6, 7]));
comp.instrument("saturation_demo", &Instrument::synth_lead())
.saturation(Saturation::new(2.5, 0.5, 0.6)) .at(10.5)
.notes(&[E4, G4, A4, B4, A4, G4, E4, D4], 0.2);
comp.instrument("eq_demo", &Instrument::sub_bass())
.eq(EQ::new(2.5, 1.0, 0.6, 250.0, 2500.0)) .at(12.5)
.notes(&[C2, C2, E2, G2, C2, E2, G2, A2], 0.2);
println!("\n3. Modulation Effects - Chorus, Phaser, Flanger");
comp.instrument("chorus_demo", &Instrument::warm_pad())
.chorus(Chorus::new(0.5, 0.003, 0.4)) .at(14.5)
.chords(
&[&[C4, E4, G4], &[A3, C4, E4], &[F3, A3, C4], &[G3, B3, D4]],
0.8,
);
comp.instrument("phaser_demo", &Instrument::warm_pad())
.phaser(Phaser::new(0.5, 0.7, 0.5, 4, 0.7)) .at(17.7)
.note(&[E4, G4, B4], 2.5);
comp.instrument("flanger_demo", &Instrument::pluck())
.flanger(Flanger::new(0.5, 3.0, 0.7, 0.7)) .at(20.5)
.note(&[A3, C4, E4], 2.5);
comp.instrument("tremolo_demo", &Instrument::warm_pad())
.tremolo(Tremolo::new(5.0, 0.8)) .at(23.5)
.note(&[C4, E4, G4], 2.5);
comp.instrument("autopan_demo", &Instrument::warm_pad())
.autopan(AutoPan::new(0.5, 0.9)) .at(26.5)
.note(&[G3, B3, D4], 2.5);
println!("\n4. Dynamic Control - Gate, Limiter");
comp.instrument("gate_demo", &Instrument::synth_lead())
.gate(Gate::new(-30.0, 10.0, 0.001, 0.05)) .at(29.5)
.notes(&[C4, 0.0, E4, 0.0, G4, 0.0, C5], 0.15);
comp.instrument("limiter_demo", &Instrument::synth_lead())
.limiter(Limiter::new(-3.0, 0.05)) .at(31.5)
.notes(&[C4, E4, G4, C5], 0.3);
println!("\n5. Lo-Fi Effects - BitCrusher, Ring Modulator");
comp.instrument("bitcrush_demo", &Instrument::synth_lead())
.bitcrusher(BitCrusher::new(4.0, 8.0, 0.7)) .at(33.5)
.notes(&[C4, E4, G4, E4], 0.3);
comp.instrument("ringmod_demo", &Instrument::synth_lead())
.ring_mod(RingModulator::new(440.0, 0.8)) .at(35.5)
.notes(&[C4, E4, G4, C5], 0.5);
println!("\n6. Comparison Demonstrations");
println!(" • Compressor: Before and after");
comp.instrument("uncomp", &Instrument::synth_lead())
.at(38.0)
.note(&[C4], 0.2)
.note(&[E4], 0.2)
.note(&[G4], 0.2)
.note(&[C5], 0.2);
comp.instrument("comp", &Instrument::synth_lead())
.compressor(Compressor::new(0.2, 6.0, 0.005, 0.05, 2.0))
.at(38.8)
.note(&[C4], 0.2)
.note(&[E4], 0.2)
.note(&[G4], 0.2)
.note(&[C5], 0.2);
println!(" • Tremolo: Slow vs Fast");
comp.instrument("tremolo_slow", &Instrument::warm_pad())
.tremolo(Tremolo::new(2.0, 0.7)) .at(40.0)
.note(&[C4, E4, G4], 2.0);
comp.instrument("tremolo_fast", &Instrument::warm_pad())
.tremolo(Tremolo::new(8.0, 0.7)) .at(42.2)
.note(&[C4, E4, G4], 2.0);
println!(" • AutoPan: Width variations");
comp.instrument("autopan_narrow", &Instrument::warm_pad())
.autopan(AutoPan::new(1.0, 0.3)) .at(44.5)
.note(&[E3, G3, B3], 1.5);
comp.instrument("autopan_wide", &Instrument::warm_pad())
.autopan(AutoPan::new(1.0, 0.9)) .at(46.2)
.note(&[E3, G3, B3], 1.5);
println!(" • EQ: Bass boost, Mid boost, Treble boost");
let eq_chord = &[C3, E3, G3, C4];
comp.instrument("eq_bass_boost", &Instrument::warm_pad())
.eq(EQ::new(3.0, 1.0, 0.5, 300.0, 2000.0))
.at(48.0)
.note(eq_chord, 1.0);
comp.instrument("eq_mid_boost", &Instrument::warm_pad())
.eq(EQ::new(0.7, 2.5, 0.7, 300.0, 2000.0))
.at(49.2)
.note(eq_chord, 1.0);
comp.instrument("eq_treble_boost", &Instrument::warm_pad())
.eq(EQ::new(0.6, 1.0, 2.5, 300.0, 2000.0))
.at(50.4)
.note(eq_chord, 1.0);
println!(" • BitCrusher: Progressive degradation");
for i in 0..6 {
let bit_depth = 16.0 - (i as f32 * 2.0);
comp.instrument(&format!("bitcrush_{}", i), &Instrument::synth_lead())
.bitcrusher(BitCrusher::new(bit_depth, (i + 1) as f32 * 2.0, 0.8))
.at(52.0 + (i as f32 * 0.3))
.note(&[A4], 0.25);
}
println!("\n7. Combined Effects - Multiple effects working together");
comp.track("delay_reverb")
.delay(Delay::new(0.25, 0.3, 0.4))
.reverb(Reverb::new(0.4, 0.5, 0.3))
.at(54.5)
.notes(&[C4, E4, G4], 0.5);
comp.instrument("production_combo", &Instrument::warm_pad())
.eq(EQ::new(0.9, 1.2, 0.8, 200.0, 3000.0))
.compressor(Compressor::new(0.25, 3.0, 0.02, 0.15, 1.3))
.chorus(Chorus::new(0.4, 0.002, 0.3))
.at(56.5)
.chords(
&[
&[C4, E4, G4, B4],
&[F3, A3, C4, E4],
&[G3, B3, D4, F4],
&[C4, E4, G4, C5],
],
0.8,
);
comp.instrument("lofi_combo", &Instrument::synth_lead())
.bitcrusher(BitCrusher::new(3.0, 12.0, 0.8))
.saturation(Saturation::new(3.0, 0.7, 0.7))
.at(60.0)
.notes(&[C5, D5, E5, G5], 0.3);
comp.instrument("mod_combo", &Instrument::warm_pad())
.phaser(Phaser::new(0.3, 0.6, 0.4, 4, 0.5))
.flanger(Flanger::new(0.4, 2.5, 0.5, 0.4))
.tremolo(Tremolo::new(4.0, 0.5))
.at(62.0)
.note(&[D3, F3, A3, C4], 2.5);
comp.instrument("stereo_combo", &Instrument::warm_pad())
.autopan(AutoPan::new(0.3, 0.7))
.chorus(Chorus::new(0.5, 0.003, 0.3))
.reverb(Reverb::new(0.5, 0.5, 0.4))
.at(65.0)
.note(&[E3, G3, B3, D4], 2.5);
comp.instrument("production_chain", &Instrument::synth_lead())
.gate(Gate::new(-35.0, 10.0, 0.001, 0.05))
.compressor(Compressor::new(0.25, 4.0, 0.01, 0.1, 1.5))
.eq(EQ::new(1.2, 1.0, 0.9, 200.0, 3000.0))
.limiter(Limiter::new(-1.0, 0.05))
.at(68.0)
.notes(&[C4, E4, G4, C5, G4, E4], 0.3);
println!("\n8. Musical Examples - Effects in context");
comp.instrument("dub_delay", &Instrument::synth_lead())
.delay(Delay::new(0.375, 0.6, 0.5))
.reverb(Reverb::new(0.6, 0.5, 0.4))
.at(70.5)
.notes(&[C4, E4, G4, A4, G4, E4, D4, C4], 0.25);
comp.instrument("phaser_progression", &Instrument::warm_pad())
.phaser(Phaser::new(0.6, 0.7, 0.5, 4, 0.6))
.at(72.5)
.note(&[C4, E4, G4], 2.0)
.note(&[F3, A3, C4], 2.0);
comp.instrument("tremolo_melody", &Instrument::synth_lead())
.tremolo(Tremolo::new(6.0, 0.6))
.delay(Delay::new(0.25, 0.4, 0.3))
.at(76.5)
.notes(&[E4, G4, A4, B4, A4, G4, E4], 0.25);
comp.instrument("autopan_space", &Instrument::warm_pad())
.autopan(AutoPan::new(0.4, 0.8))
.reverb(Reverb::new(0.6, 0.6, 0.4))
.at(78.5)
.chords(&[&[F3, A3, C4], &[G3, B3, D4], &[E3, G3, B3]], 1.5);
comp.instrument("ringmod_drums", &Instrument::sub_bass())
.ring_mod(RingModulator::new(300.0, 0.6))
.at(83.0)
.drum_grid(16, 0.125, |g| g
.sound(DrumType::Kick, &[0, 4, 8, 12])
.sound(DrumType::Snare, &[4, 12])
.sound(DrumType::HiHatClosed, &[0, 2, 4, 6, 8, 10, 12, 14]));
comp.instrument("finale", &Instrument::warm_pad())
.chorus(Chorus::new(0.4, 0.003, 0.3))
.phaser(Phaser::new(0.4, 0.6, 0.4, 4, 0.4))
.flanger(Flanger::new(0.3, 2.0, 0.5, 0.3))
.tremolo(Tremolo::new(3.0, 0.4))
.autopan(AutoPan::new(0.25, 0.5))
.reverb(Reverb::new(0.7, 0.6, 0.5))
.at(85.0)
.note(&[C3, E3, G3, C4, E4, G4], 4.0);
println!("\n▶️ Playing comprehensive effects showcase...");
println!(" Duration: ~89 seconds\n");
println!(" 💎 Effects Demonstrated:");
println!(" CORE EFFECTS:");
println!(" • Delay, Reverb, Distortion");
println!(" DYNAMIC EFFECTS:");
println!(" • Compressor, Saturation, EQ");
println!(" MODULATION EFFECTS:");
println!(" • Chorus, Phaser, Flanger, Tremolo, AutoPan");
println!(" DYNAMIC CONTROL:");
println!(" • Gate, Limiter");
println!(" LO-FI EFFECTS:");
println!(" • BitCrusher, Ring Modulator");
println!(" COMBINATIONS:");
println!(" • Multiple effects working together");
println!(" • Production-ready effect chains");
let mixer = comp.into_mixer();
let engine = AudioEngine::new()?;
engine.play_mixer(&mixer)?;
println!("\n✅ Showcase complete!");
println!(" All {} audio effects in one comprehensive example!", 15);
println!(" Experiment with parameters to craft your unique sound!");
Ok(())
}