Currently, the Rust ecosystem has a handful of audio driver wrappers (I’m not delving too deeply into each crate, if you want to add details leave a comment)
(forgive the absence of links, discourse won’t let me post them)
- MacOS, Linux, Windows (and wasm?)
- uses an “EventLoop” abstraction to handle multiple streams to a single device
- Unclear on lock-free behavior in the audio thread
- Some ideas about a “Host” API for multiple backends, unclear on its status
- Linux only
- unclear if supported on MacOS
- MacOS only
- Wraps the AudioInput/Output audio units, not a direct wrapper around the C API (for the moment)
- bindings to the PortAudio library
- probably the most battle-tested audio library out there
I don’t think any of them are perfect. Ideally there should be something along these lines:
- Support for MacOS, Windows, Linux, iOS, Android, Web
- Absolute thread safety.
- Support exclusive mode where available
- Completely lock/wait free in any code that needs to run on the audio thread not supplied by a user
- Enumerate available devices, and initiate a stream for a device.
More debatable features:
- Support for multiple driver backends in the same target
- Multiple streams per device (personally, I’m against this)
- Polling and callback API
- Audio Buffer abstraction, with interleaving/deinterleaving methods
- Syncing input/output devices in a single callback
- Sensible defaults, optional configuration for users. Easy things are easy, complex things are possible.
I’d like to advocate for an API similar to Timur Doumler’s work on libstdaudio, and something a lot simpler than JUCE, cpal, or PortAudio.
So thoughts and opinions? Do we need a different HAL or is cpal good enough for everyone?