The cpal and rodio libraries (audio playback)


#1

Here is a quick project update about the cpal and rodio libraries.

Cpal

The cpal library is a pure-Rust low level cross-platform library that allows one to submit PCM to the audio output of the machine. You select an endpoint (or use the system’s default), a format amongst the ones supported, and then you write the PCM to the output buffer from time to time. You can check the beep example here.

Cpal has existed for around six months now, but it has recently received a design overhaul to be lower level and less magical. You have to explicitely choose a format and stick to it now, instead of getting conversions automatically handled for you.

Support for platforms:

  • Windows (WASAPI): should just work. It’s the best supported platform.
  • Linux (ALSA): mostly works. There are some quicks with the supported formats, and poor error handling. The biggest problem is that ALSA has a poor documentation, so if you have some knowledge about it help would be appreciated.
  • OS X (coreaudio): compilation error. Coreaudio used to work thanks to @mindtree, however it did not survive the design overhaul. There is no continuous integration for OS X and I don’t have any Mac, so there’s no way for me to work on this one.
  • Other platforms fall back to a null implementation. Cpal should compile everywhere but return an error at runtime if the platform is not supported. I will definitely add support for emscripten once Rust has a clean way to use emscripten, and maybe Android on the long term. If you want to add other platforms, contributions are of course welcome!

Rodio

The rodio library is the high level counterpart of cpal. It allows one to easily play sounds using a background thread.

See for example the music_wav example:

extern crate rodio;

use std::io::BufReader;

fn main() {
    let endpoint = rodio::get_default_endpoint().unwrap();

    let file = std::fs::File::open("examples/music.wav").unwrap();
    let music = rodio::play_once(&endpoint, BufReader::new(file));

    music.sleep_until_end();
}

Warning: rodio doesn’t work with Rust 1.3 and below because of an ICE that was only recently fixed. You will need to use the beta or nightly versions.

Rodio also handles various corner cases for you, for example you don’t get an error if the audio output device is disconnected in the middle of the application.

The supported formats are only:

  • WAV thanks to hound (pure Rust).
  • Vorbis thanks to C bindings. However there are mysterious crashes or no sound output.

And that’s the biggest problem of rodio right now. No mp3 support, poor vorbis support. Unfortunately I don’t know enough about lossy audio compression to write decoders myself.

Hopefully the situation improves and Rodio becomes a good way to just play some sounds.


Using rust for audio output
#2

I was wondering if someone was working on something like this. Good work! Perfect complement to Glutin and Glium.


#3

Great stuff @tomaka - really excited about the new lower level design of cpal! Seems much closer to what I’d be after in a purely rust, portable, low level audio backend!

Hopefully I can get around to updating (and cleaning up) the coreaudio backend sometime soon.


#4

This is exactly what I was looking for!

I will try to port my soft-synthesizer from java to Rust.