The cpal and rodio libraries (audio playback)

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.

15 Likes

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

1 Like

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.

This is exactly what I was looking for!

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

Might be a dumb question: Is this forum the best way to communicate the Rodio related things?

The real question want to ask @tomaka, is it an example to show how to play the music in a background thread, as when i click the play button, the music is ok, but the screen frozen.
Any advice?

You may want to create an issue on the rodio project's issue tracker instead of replying to a 5 year old forum thread.

The project's repo also has several examples. If you're having problems, check the code out locally and try running one of those.

I already ran almost all of the examples. also grep Thread, couldn't find any.
But I will dig into more. Also if can provide any opensource project that actively using Rodio that will be great.

From the GUI part, I am using Druid, try to create a PoC music-player, to see if can use Rodio/Druid in PROD.

The Rust Audio forum is probably the best place to ask questions about rodio. Feel free to post here instead if you prefer, especially if your questions are about general topics like threading—but please create a new topic rather than re-using old ones.

4 Likes