Useful Rust Audio Crates

Audio backend crates

How audio works (in a nutshell...)

Usually, when working with audio, whether it's with Rust or any other programming language, you need an interface with OS audio drivers, which are usually wrapped into higher-level libraries, such as JACK, or PortAudio. They all have usually similar APIs, based on audio callbacks.

Audio callbacks

Real-time audio is tightly time-constrained, a continuous audio stream in stereo for instance usually needs 44100 (or 48000, or higher) audio samples (values) per second in order to be viable. In order to achieve this, audio is usually processed or synthesized in buffers (usually 512 samples or lower), to be more efficient. The APIs of most audio backend libraries provide buffer-based audio callback interfaces that will give you an input buffer, an output buffer, or both (duplex). In this callback, you can for example read a buffer of audio inputs (usually a f32 slice) that's given to you by the backend, and write it back to the audio output buffer after you've done your processing:

#![allow(unused)]
fn main() {
// a passthrough example, 
// If our sample-rate is 48000 Hz, and our buffer-sizer is 128 samples,
// then our function is going to be called 375 times in one second:
let my_callback = |inputs: &[f32], outputs: &mut[f32]| {
    for s in inputs.len() {
        outputs[s] = inputs[s];
    }
}
}

Which backend crate should I use?

If you're on Linux, JACK is probably the easiest and most efficient in terms of performance. Otherwise, for other platforms, cpal is probably safer, but a little harder to use, especially if you need both audio inputs and outputs, because the audio processing callbacks are not "duplex", meaning you need to have 2 separate audio callbacks (one for inputs, one for outputs), running in two different contexts of execution. The difficulty with this is that, if you need to exchange audio data between the two callbacks, you will have to use a shared ringbuffer (mpsc-like). You can find a very good crate for this here:

JACK (Jack Audio Connection Kit)

  • Use case: recommended for low-latency audio on Linux.

  • Git: https://github.com/RustAudio/rust-jack

  • Duplex callback: YES

  • Platforms:

    • Linux (recommended)
    • Should be harder to make it work on macOS and Windows.
  • Dependencies:

  • Documentation: https://rustaudio.github.io/rust-jack/

  • Code examples:

  • Utilities:

    • qjackctl, to dynamically patch/connect the audio clients in a GUI graph.
    • qpwgraph, same but works with pipewire-jack
  • Comments:

    • If using with PipeWire (with pipewire-jack), run pw-jack cargo-run in order to enable PipeWire to emulate a jack client.
    • Otherwise, don't forget to start the JACK server before running your executable (manually in the terminal, or with qjackctl)

cpal

cxx-juce (bindings)