tunes 1.1.0

A music composition, synthesis, and audio generation library
Documentation
use tunes::prelude::*;

/// Demonstrate swing timing (straight vs swung)
fn main() -> anyhow::Result<()> {
    println!("\n🎵 Example: Swing/Groove Timing\n");

    let engine = AudioEngine::new()?;
    let mut comp = Composition::new(Tempo::new(120.0));

    // Straight hi-hats (no swing)
    comp.track("hihat_straight")
        .pan(-0.5)
        .at(0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0);

    // Swung hi-hats (triplet feel - 0.67)
    comp.track("hihat_swing")
        .pan(0.5)
        .swing(0.67) // Triplet swing!
        .at(2.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0);

    // Heavy swing (0.75)
    comp.track("hihat_heavy")
        .pan(0.0)
        .swing(0.75) // Heavy swing
        .at(4.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0)
        .drum(DrumType::HiHatClosed, 0.0);

    println!("✓ Swing values:");
    println!("  - 0.5 (straight timing - no swing)");
    println!("  - 0.67 (triplet swing - jazzy)");
    println!("  - 0.75 (heavy swing - extreme)\n");

    engine.play_mixer(&comp.into_mixer())?;
    Ok(())
}