| Crates.io | auxide |
| lib.rs | auxide |
| version | 0.3.1 |
| created_at | 2026-01-03 23:19:25.391297+00 |
| updated_at | 2026-01-17 00:51:00.539678+00 |
| description | Real-time-safe, deterministic audio graph kernel |
| homepage | |
| repository | https://github.com/Michael-A-Kuykendall/auxide |
| max_upload_size | |
| id | 2020922 |
| size | 1,653,775 |
A real-time-safe, deterministic audio graph kernel for Rust.
Build reliable audio tools, DSP chains, and synthesis engines with a focus on correctness, performance, and simplicity.
Auxide fills a gap in the Rust audio ecosystem: a low-level, RT-safe kernel for executing audio graphs deterministically. Unlike full DAWs or plugin hosts, it's a programmable building block—think of it as the engine under the hood.
Audio processing as a directed acyclic graph (DAG):
This model powers everything from modular synths to game audio engines.
Existing options are either:
Auxide is engineer-friendly: Minimal API, zero-cost abstractions, RT-safe by default. It's designed for software developers building audio tools, not musicians coding live.
| Feature | Auxide | SuperCollider | Rodio | CPAL |
|---|---|---|---|---|
| RT-Safe | ✅ | ❌ | ❌ | ✅ |
| Graph-Based | ✅ | ✅ | ❌ | ❌ |
| Deterministic | ✅ | ❌ | ❌ | ❌ |
| Minimal API | ✅ | ❌ | ✅ | ✅ |
| Rust Native | ✅ | ❌ | ✅ | ✅ |
Auxide is open source but not open contribution. The project is maintained by @Michael-A-Kuykendall; unsolicited PRs are closed by default. See CONTRIBUTING.md and GOVERNANCE.md for the collaboration policy.
Auxide's three-phase pipeline ensures reliability:
graph LR
A[Graph] --> B[Plan]
B --> C[Runtime]
C --> D[Audio Blocks]
Violations caught at compile-time or runtime with clear errors.
Install: cargo add auxide
Generate a sine wave:
use auxide::graph::{Graph, NodeType, PortId, Rate};
use auxide::plan::Plan;
use auxide::rt::Runtime;
fn main() {
// Build graph
let mut graph = Graph::new();
let osc = graph.add_node(NodeType::SineOsc { freq: 440.0 });
let sink = graph.add_node(NodeType::OutputSink);
graph.add_edge(auxide::graph::Edge {
from_node: osc,
from_port: PortId(0),
to_node: sink,
to_port: PortId(0),
rate: Rate::Audio,
}).unwrap();
// Compile plan
let plan = Plan::compile(&graph, 64).unwrap();
// Run runtime
let mut runtime = Runtime::new(plan, &graph, 44100.0);
let mut out = vec![0.0; 64];
runtime.process_block(&mut out).unwrap();
println!("Generated {} samples of 440Hz sine", out.len());
}
Run this and hear a pure tone—your first Auxide audio!
Route one signal to multiple processors, then mix back:
use auxide::graph::{Graph, NodeType, PortId, Rate};
use auxide::plan::Plan;
use auxide::rt::Runtime;
fn main() {
let mut graph = Graph::new();
let osc = graph.add_node(NodeType::SineOsc { freq: 440.0 });
let gain1 = graph.add_node(NodeType::Gain { gain: 0.5 });
let gain2 = graph.add_node(NodeType::Gain { gain: 0.3 });
let mixer = graph.add_node(NodeType::Mix);
let sink = graph.add_node(NodeType::OutputSink);
// Fan out: osc feeds both gains
graph.add_edge(auxide::graph::Edge {
from_node: osc,
from_port: PortId(0),
to_node: gain1,
to_port: PortId(0),
rate: Rate::Audio,
}).unwrap();
graph.add_edge(auxide::graph::Edge {
from_node: osc,
from_port: PortId(0),
to_node: gain2,
to_port: PortId(0),
rate: Rate::Audio,
}).unwrap();
// Mix attenuated signals
graph.add_edge(auxide::graph::Edge {
from_node: gain1,
from_port: PortId(0),
to_node: mixer,
to_port: PortId(0),
rate: Rate::Audio,
}).unwrap();
graph.add_edge(auxide::graph::Edge {
from_node: gain2,
from_port: PortId(0),
to_node: mixer,
to_port: PortId(1),
rate: Rate::Audio,
}).unwrap();
graph.add_edge(auxide::graph::Edge {
from_node: mixer,
from_port: PortId(0),
to_node: sink,
to_port: PortId(0),
rate: Rate::Audio,
}).unwrap();
let plan = Plan::compile(&graph, 64).unwrap();
let mut runtime = Runtime::new(plan, &graph, 44100.0);
let mut out = vec![0.0; 64];
runtime.process_block(&mut out).unwrap();
// out now contains mixed, attenuated sine
}
This demonstrates parallel processing and signal combination—core to audio graphs.
Process entire buffers for non-real-time tasks:
use auxide::graph::{Graph, NodeType, PortId, Rate};
use auxide::plan::Plan;
use auxide::rt::Runtime;
fn main() {
let mut graph = Graph::new();
let osc = graph.add_node(NodeType::SineOsc { freq: 1000.0 });
let sink = graph.add_node(NodeType::OutputSink);
graph.add_edge(auxide::graph::Edge {
from_node: osc,
from_port: PortId(0),
to_node: sink,
to_port: PortId(0),
rate: Rate::Audio,
}).unwrap();
let plan = Plan::compile(&graph, 1024).unwrap();
let mut runtime = Runtime::new(plan, &graph, 44100.0);
// Render 1 second of audio
let mut buffer = vec![0.0; 44100];
for chunk in buffer.chunks_mut(1024) {
runtime.process_block(chunk).unwrap();
}
// buffer now holds 1s of 1kHz sine
// Save to WAV, analyze, etc.
}
Perfect for batch processing, analysis, or exporting.
Check examples/ for:
basic_sine.rs: Simple oscillator.gain_chain.rs: Signal processing chain.mixer.rs: Multi-input mixing.offline_render.rs: Full buffer rendering.am_synth.rs: Amplitude modulation demo.filter_chain.rs: Basic filter approximation.sequencer.rs: Note sequencing.Clone the repo and run cargo run --example <name> to explore.
Extend NodeType with custom oscillators, filters. Use Auxide for the graph engine.
Dynamic graphs for sound design—RT-safe for frame rates.
Quickly test ideas without RT constraints.
Pair with cpal for playback, hound for file I/O.
Auxide is the foundation—build your tools on top.
Issues and PRs welcome. See CONTRIBUTING.md for guidelines.
🚀 If Auxide helps you, consider sponsoring — 100% of support goes to keeping it free forever.
🎯 Become a Sponsor | See our amazing sponsors 🙏
MIT