Crate cpal [] [src]

How to use cpal

Here are some concepts cpal exposes:

  • An endpoint is a target where the data of the audio channel will be played.
  • A voice is an open audio channel which you can stream audio data to. You have to choose which endpoint your voice targets before you create one.
  • An event loop is a collection of voices. Each voice must belong to an event loop, and all the voices that belong to an event loop are managed together.

In order to play a sound, you first need to create an event loop:

use cpal::EventLoop;
let event_loop = EventLoop::new();

Then choose an endpoint. You can either use the default endpoint with the default_endpoint() function, or enumerate all the available endpoints with the endpoints() function. Beware that default_endpoint() returns an Option in case no endpoint is available on the system.

// Note: we call `unwrap()` because it is convenient, but you should avoid doing that in a real
// code.
let endpoint = cpal::default_endpoint().expect("no endpoint is available");

Before we can create a voice, we must decide what the format of the audio samples is going to be. You can query all the supported formats with the supported_formats() method, which produces a list of SupportedFormat structs which can later be turned into actual Format structs. If you don't want to query the list of formats, you can also build your own Format manually, but doing so could lead to an error when building the voice if the format ends up not being supported.

Note: the supported_formats() method could return an error for example if the device has been disconnected.

let mut supported_formats_range = endpoint.supported_formats()
                                          .expect("error while querying formats");
let format ="no supported format?!")

Now that we have everything, we can create a voice from that event loop:

let voice_id = event_loop.build_voice(&endpoint, &format).unwrap();

The value returned by build_voice() is of type VoiceId and is an identifier that will allow you to control the voice.

There is a last step to perform before going forward, which is to start the voice. This is done with the play() method on the event loop.;

Once everything is done, you must call run() on the event_loop. |_voice_id, _buffer| {
    // write data to `buffer` here

Note: Calling run() will block the thread forever, so it's usually best done in a separate thread.

While run() is running, the audio device of the user will from time to time call the callback that you passed to this function. The callback gets passed the voice ID, and a struct of type UnknownTypeBuffer that represents the buffer that must be filled with audio samples. The UnknownTypeBuffer can be one of I16, U16 or F32 depending on the format that was passed to build_voice.

In this example, we simply simply fill the buffer with zeroes.

use cpal::UnknownTypeBuffer; |_voice_id, mut buffer| {
    match buffer {
        UnknownTypeBuffer::U16(mut buffer) => {
            for elem in buffer.iter_mut() {
                *elem = u16::max_value() / 2;
        UnknownTypeBuffer::I16(mut buffer) => {
            for elem in buffer.iter_mut() {
                *elem = 0;
        UnknownTypeBuffer::F32(mut buffer) => {
            for elem in buffer.iter_mut() {
                *elem = 0.0;



Represents a buffer that must be filled with audio data.


An opaque type that identifies an endpoint that is capable of playing audio.


An iterator for the list of formats that are supported by the backend.


Collection of voices managed together.


Describes a format.


Describes a range of supported formats.


An iterator that produces a list of formats supported by the endpoint.


Identifier of a voice in an events loop.



Possible position of a channel.


Error that can happen when creating a Voice.


Error that can happen when enumerating the list of supported formats.


Format that each sample has.


This is the struct that is provided to you by cpal when you want to write samples to a buffer.



Trait for containers that contain PCM data.



Return the default endpoint, or None if no device is available.


Return an iterator to the list of formats that are supported by the system.

get_default_endpoint [

Deprecated. Use default_endpoint() instead.

get_endpoints_list [

Deprecated. Use endpoints() instead.

Type Definitions


Number of channels.