Low-level library for audio input and output, written in Rust.
For higher-level audio playback and capture, consider Rodio or similar libraries.
| Platform | Default Backend | Optional Backends |
|---|---|---|
| Android | AAudio | - |
| BSD | ALSA | JACK, PipeWire, PulseAudio |
| iOS | CoreAudio | - |
| Linux | ALSA | JACK, PipeWire, PulseAudio |
| macOS | CoreAudio | JACK |
| tvOS | CoreAudio | - |
| WebAssembly | Web Audio API | Audio Worklet |
| Windows | WASAPI | ASIO, JACK |
On Linux, building cpal requires the ALSA development files: libasound2-dev on Debian and Ubuntu, alsa-lib-devel on Fedora.
ALSA is needed even when using JACK, PipeWire, or PulseAudio.
The optional realtime-dbus feature additionally requires libdbus-1-dev (Debian/Ubuntu) or dbus-devel (Fedora). See ALSA Real-Time Priority Promotion.
The minimum Rust version required depends on which audio backend and features you're using, as each platform has different dependencies:
| Backend | Platforms | MSRV |
|---|---|---|
| AAudio | Android | 1.85 |
| ALSA | Linux, BSD | 1.85 |
| CoreAudio | macOS, iOS | 1.85 |
| CoreAudio | tvOS | nightly |
| JACK | Linux, BSD, macOS, Windows | 1.85 |
| PipeWire | Linux, BSD | 1.85 |
| PulseAudio | Linux, BSD | 1.88 |
| WASAPI / ASIO | Windows | 1.85 |
WASM (wasm32-unknown) |
WebAssembly | 1.85 |
WASM (wasm32-wasip1) |
WebAssembly | 1.85 |
WASM (audioworklet) |
WebAssembly | nightly |
The audioworklet backend additionally requires -Zbuild-std with atomics support enabled.
| Feature | Platform | Description |
|---|---|---|
asio |
Windows | ASIO backend for low-latency audio, bypassing the Windows audio stack. Requires ASIO drivers and LLVM/Clang. See the ASIO setup guide. |
audioworklet |
WebAssembly (wasm32-unknown-unknown) |
Audio Worklet backend for lower-latency web audio than the default Web Audio API, running audio on a dedicated thread. Requires atomics support (RUSTFLAGS="-C target-feature=+atomics,+bulk-memory,+mutable-globals") and Cross-Origin headers for SharedArrayBuffer. See the audioworklet-beep example. |
custom |
All | User-defined backend implementations for audio systems not natively supported by CPAL. See examples/custom.rs. |
jack |
Linux, BSD, macOS, Windows | JACK Audio Connection Kit backend for pro-audio routing and inter-application connectivity. Requires libjack-jackd2-dev (Debian/Ubuntu) or jack-devel (Fedora). |
pipewire |
Linux, BSD | PipeWire media server backend. Requires libpipewire-0.3-dev (Debian/Ubuntu) or pipewire-devel (Fedora). |
pulseaudio |
Linux, BSD | PulseAudio sound server backend. Requires libpulse-dev (Debian/Ubuntu) or pulseaudio-libs-devel (Fedora). |
realtime |
Linux, BSD, Windows, Android | Raises the audio callback thread to real-time or high-priority scheduling for lower latency. On Linux/BSD, requires rtprio granted in limits.conf (e.g. @audio - rtprio 95) unless realtime-dbus is also enabled. |
realtime-dbus |
Linux, BSD | Uses rtkit via D-Bus for RT scheduling on Linux/BSD desktop systems, removing the need for manual limits.conf setup. Implies realtime on all platforms. Requires libdbus-1-dev on Linux/BSD. |
wasm-bindgen |
WebAssembly (wasm32-unknown-unknown) |
Web Audio API backend for browser-based audio; required for any WebAssembly audio support. See the wasm-beep example. |
See the beep example for selecting the backend at runtime.
The location of ASIO SDK is exposed to CPAL by setting the CPAL_ASIO_DIR environment variable.
The build script will try to find the ASIO SDK by following these steps in order:
CPAL_ASIO_DIR is set and if so use the path to point to the SDK.CPAL_ASIO_DIR to the output of std::env::temp_dir().join("asio_sdk").CPAL_ASIO_DIR will be set to the output of std::env::temp_dir().join("asio_sdk").In an ideal situation you don't need to worry about this step.
Install LLVM/Clang: bindgen, the library used to generate bindings to the C++ SDK, requires clang. Download and install LLVM from http://releases.llvm.org/download.html under the "Pre-Built Binaries" section.
Set LIBCLANG_PATH: Add the LLVM bin directory to a LIBCLANG_PATH environment variable. If you installed LLVM to the default directory, this should work in the command prompt:
bat
setx LIBCLANG_PATH "C:\Program Files\LLVM\bin"
Install ASIO Drivers (optional for testing): If you don't have any ASIO devices or drivers available, you can download and install ASIO4ALL from http://www.asio4all.org/. Be sure to enable the "offline" feature during installation.
Visual Studio: The build script assumes Microsoft Visual Studio is installed. It will try to find vcvarsall.bat and execute it with the right host and target architecture. If needed, you can manually execute it:
bat
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
For more information see the vcvarsall.bat documentation.
Cargo.toml:toml
cpal = { version = "*", features = ["asio"] }
rust
let host = cpal::host_from_id(cpal::HostId::Asio)
.expect("failed to initialise ASIO host");
When Windows is the host and target OS, the build script supports all cross-compilation targets supported by the MSVC compiler.
It is also possible to compile Windows applications with ASIO support on Linux and macOS using the MinGW-w64 toolchain.
Requirements:
CPLUS_INCLUDE_PATH environment variableCPLUS_INCLUDE_PATH environment variableExample for macOS (targeting x86_64-pc-windows-gnu with mingw-w64 installed via brew):
export CPLUS_INCLUDE_PATH="$CPLUS_INCLUDE_PATH:/opt/homebrew/Cellar/mingw-w64/11.0.1/toolchain-x86_64/x86_64-w64-mingw32/include"
If you are interested in using CPAL with WebAssembly, please see this guide in our Wiki which walks through setting up a new project from scratch. Some of the examples in this repository also provide working configurations that you can use as reference.
If you receive errors about no default input or output device:
pw-cli infopulseaudio --checkWhen PipeWire or PulseAudio is running, it holds the ALSA default device exclusively. A second stream attempting to open it via the ALSA host will fail with a DeviceBusy error. To route audio through the sound server via ALSA, use the bridge devices pipewire or pulse instead of default. Better yet, use the pipewire or pulseaudio cpal features for native integration.
On targets without a sound server, address devices directly as hw: or plughw:.
BufferSize::Default uses the system-configured device default, which on ALSA can range from a PipeWire quantum (typically 1024 frames) to u32::MAX on misconfigured or exotic hardware. A very deep buffer causes samples to be consumed far faster than audible playback, making audio appear to fast-forward ahead of actual output.
Configure the system and/or request a fixed size in your application:
| System | File | Setting |
|---|---|---|
| ALSA | ~/.asoundrc or /etc/asound.conf |
buffer_size, periods * period_size |
| PipeWire | ~/.config/pipewire/pipewire.conf.d/ |
default.clock.quantum |
| PulseAudio | ~/.config/pulse/daemon.conf |
default-fragments * default-fragment-size-msec |
config.buffer_size = cpal::BufferSize::Fixed(1024);
Query device.default_output_config()?.buffer_size() for valid ranges. Smaller buffers reduce latency but increase CPU load and the risk of glitches.
RT promotion is only attempted for a whitelist of PCM types: direct hardware PCMs (hw:) and pure format-conversion plugins (linear, A-law, mu-law, ADPCM, float, IEC 958).
RealtimeDenied is emitted on the error callback only when promotion is attempted but fails, which happens when the process lacks the resource limits to acquire SCHED_FIFO. While RT priority is desirable for low latency, the stream will continue to play at the default scheduling priority.
With the realtime-dbus feature, rtkit arranges the necessary limits over D-Bus on typical desktop systems. With the plain realtime feature, you must ensure that rtprio is granted yourself. Add to /etc/security/limits.d/audio.conf and ensure the user is member of the audio group:
@audio - rtprio 95
then add the user to the audio group (usermod -aG audio "$USER") and re-login. The same group may anyway be needed to grant access to ALSA device files via udev on systems that do not arrange this automatically via logind.
If you are unable to build the library:
CPAL_ASIO_DIR and LIBCLANG_PATH are set and LLVM is installedCPAL comes with several examples in examples/.
Run an example with:
cargo run --example beep
For platform-specific features, enable the relevant features:
cargo run --example beep --features asio # Windows ASIO backend
cargo run --example beep --features jack # JACK backend
cargo run --example beep --features pipewire # PipeWire backend
cargo run --example beep --features pulseaudio # PulseAudio backend
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
Licensed under the Apache License, Version 2.0. See LICENSE for details.