tunes 0.2.0

A music composition, synthesis, and audio generation library
Documentation

tunes

A standalone Rust library for music composition, synthesis, and audio generation. Build complex musical pieces with an intuitive, expressive API — no runtime dependencies required.

Perfect for algorithmic music, game audio, generative art, and interactive installations.

Features

  • Music Theory: Scales, chords, patterns, progressions, and transposition
  • Composition DSL: Fluent API for building musical sequences
  • Sections & Arrangements: Create reusable sections (verse, chorus, bridge) and arrange them
  • Synthesis: FM synthesis, filter envelopes, wavetable oscillators
  • Sample Playback: Load and play WAV files with pitch shifting
  • Rhythm & Drums: Drum grids, euclidean rhythms, 808-style synthesis, and pattern sequencing
  • Instruments: Pre-configured synthesizers, bass, pads, leads, and more
  • Effects, Automation and Filters: Delay, reverb, distortion, chorus, modulation, tremolo, autopan, gate, limiter, compressor, bitcrusher, eq, phaser, flanger, saturation, filters
  • Musical Patterns: Arpeggios, ornaments, tuplets, classical techniques
  • Algorithmic Sequences: Primes, Fib, 2^x, Markov, L-map, Collatz, Euclidean, Golden ratio, random/bounded walks, Thue-Morse, Recamán's, Van der Corput, L-System, Cantor, Shepherd, Cellular Automaton, and many more
  • Tempo & Timing: Tempo changes, time signatures (3/4, 5/4, 7/8, etc.), key signatures with modal support
  • Key Signatures & Modes: Major, minor, and all 7 Greek modes (Dorian, Phrygian, Lydian, etc.)
  • Real-time Playback: Cross-platform audio output via cpal
  • WAV Import/Export: Load samples and render compositions to WAV files
  • MIDI Export: Export compositions to Standard MIDI Files with proper metadata

Installation

Add this to your Cargo.toml:

[dependencies]
tunes = "0.1.0"

Platform Requirements

Linux users need ALSA development libraries:

# Debian/Ubuntu
sudo apt install libasound2-dev

# Fedora/RHEL
sudo dnf install alsa-lib-devel

macOS and Windows work out of the box with no additional dependencies.

Quick Start: Super simple!!

Real-time Playback

use tunes::prelude::*;

fn main() -> Result<(), anyhow::Error> {
    let engine = AudioEngine::new()?;
    let mut comp = Composition::new(Tempo::new(120.0));
    let eighth = comp.tempo().eighth_note();  //getting this value to use in the next example

    // This is where you can do everything. 
    // Notes and chords can be input as floats with frequencies in hz or using or by prelude constants
    // Durations can be input as a duration of seconds as a float or using durations inferred by tempo
    
    comp.instrument("piano", &Instrument::electric_piano())
        .note(&[C4], 0.5)    //plays a c4 for half a second
        .note(&[280.0], eighth); //plays 280.0 hz note for half a second
        //continue chaining methods after the second note if you want.
    engine.play_mixer(&comp.into_mixer())?;
    Ok(())
}

Export to WAV

use tunes::prelude::*;

fn main() -> Result<(), anyhow::Error> {
    let mut comp = Composition::new(Tempo::new(120.0));

    // Create a melody with instruments and effects
    comp.instrument("lead", &Instrument::synth_lead())
        .filter(Filter::low_pass(1200.0, 0.6))
        .notes(&[C4, E4, G4, C5], 0.5);

    // Export to WAV file
    let mut mixer = comp.into_mixer();
    mixer.export_wav("my_song.wav", 44100)?;
    Ok(())
}

Sample Playback

use tunes::prelude::*;

fn main() -> Result<(), anyhow::Error> {
    let mut comp = Composition::new(Tempo::new(120.0));

    // Load samples (drums, vocals, any WAV file)
    comp.load_sample("kick", "samples/kick.wav")?;
    comp.load_sample("snare", "samples/snare.wav")?;

    // Use samples in your composition
    comp.track("drums")
        .sample("kick")                    // Play at normal speed
        .sample("snare")
        .sample("kick")
        .sample_with_rate("snare", 2.0);   // Double speed (pitch up)

    // Mix samples with synthesis
    comp.instrument("bass", &Instrument::sub_bass())
        .notes(&[C2, C2, G2, G2], 0.5);

    let mixer = comp.into_mixer();
    let engine = AudioEngine::new()?;
    engine.play_mixer(&mixer)?;
    Ok(())
}

MIDI Export

use tunes::prelude::*;

fn main() -> Result<(), anyhow::Error> {
    let mut comp = Composition::new(Tempo::new(120.0));

    // Create a composition
    comp.instrument("melody", &Instrument::synth_lead())
        .notes(&[C4, E4, G4, C5], 0.5);

    comp.track("drums")
        .drum_grid(16, 0.125)
        .kick(&[0, 4, 8, 12])
        .snare(&[4, 12]);

    // Export to MIDI file
    let mixer = comp.into_mixer();
    mixer.export_midi("song.mid")?;
    Ok(())
}

Comparison with Other Music Programming Libraries

tunes occupies a unique position in the music programming landscape:

Feature SuperCollider Sonic Pi Leipzig Strudel tunes Music21
Type safety No No No (Clojure) Partial (TS) Yes (Rust) No
Real-time audio Yes Yes Yes (Overtone) Yes (Web Audio) Yes No
Sample playback Yes Yes Yes (Overtone) Yes Yes No
WAV export Yes (manual) No Via Overtone No (browser) Yes (easy) Yes
MIDI export Yes No No No Yes Yes
Easy to learn No Yes Medium Yes Yes Yes
No dependencies No (needs SC) No (needs Ruby) No (Clojure+SC) No (browser/Node) Yes No
Algorithmic patterns Yes Yes Yes Yes Yes Yes
Music theory Manual Manual Yes Some Yes (built-in) Yes
Standalone binary No No No No Yes No
Embeddable No No No No Yes No

When to use tunes

tunes excels at:

  • Building Rust applications with music generation (games, art installations, tools)
  • Algorithmic composition with type-safe APIs
  • Offline music generation and batch processing
  • Learning music programming without complex setup
  • Prototyping musical ideas with immediate feedback

Use alternatives if you need:

  • SuperCollider: Extreme synthesis flexibility and live coding ecosystem
  • Sonic Pi: Classroom-ready live coding with visual feedback
  • Leipzig: Functional composition with Clojure's elegance
  • Strudel: Browser-based collaboration and live coding
  • Music21: Academic music analysis and score manipulation

tunes' unique position

tunes is the only standalone, embeddable, type-safe music library with synthesis + sample playback. It compiles to a single binary with no runtime dependencies, making it ideal for:

  • Rust game developers (Bevy, ggez, etc.)
  • Desktop music applications
  • Command-line music tools
  • Embedded audio systems

Documentation

Run cargo doc --open to view the full API documentation with detailed examples for each module.

Testing

cargo test
  • The library includes 607 comprehensive tests and 178 doc tests ensuring reliability and correctness.

Examples

Run the included 50 examples to hear the library in action:

# Sample playback (WAV file loading and playback)
cargo run --release --example sample_playback_demo

# Export to WAV file
cargo run --release --example wav_export_demo

# Synthesis showcase (FM, filters, envelopes)
cargo run --release --example synthesis_demo

# Theory and scales
cargo run --example theory_demo

# Effects and effect automation (dynamic parameter changes over time)
cargo run --example effects_showcase
cargo run --example automation_demo

# And many more...

Note: Use --release for examples with complex synthesis to avoid audio underruns.

License

MIT OR Apache-2.0

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.