Update docs for removal of the `EventLoop`
This commit is contained in:
parent
27245444a7
commit
f34a062fac
161
src/lib.rs
161
src/lib.rs
|
@ -7,25 +7,21 @@
|
||||||
//! least one [**DefaultHost**](./struct.Host.html) that is guaranteed to be available.
|
//! least one [**DefaultHost**](./struct.Host.html) that is guaranteed to be available.
|
||||||
//! - A [**Device**](./struct.Device.html) is an audio device that may have any number of input and
|
//! - A [**Device**](./struct.Device.html) is an audio device that may have any number of input and
|
||||||
//! output streams.
|
//! output streams.
|
||||||
//! - A stream is an open flow of audio data. Input streams allow you to receive audio data, output
|
//! - A [**Stream**](./trait.Stream.html) is an open flow of audio data. Input streams allow you to
|
||||||
//! streams allow you to play audio data. You must choose which **Device** will run your stream
|
//! receive audio data, output streams allow you to play audio data. You must choose which
|
||||||
//! before you can create one. Often, a default device can be retrieved via the **Host**.
|
//! **Device** will run your stream before you can create one. Often, a default device can be
|
||||||
//! - An [**EventLoop**](./struct.EventLoop.html) is a collection of streams being run by one or
|
//! retrieved via the **Host**.
|
||||||
//! more **Device**s under a single **Host**. Each stream must belong to an **EventLoop**, and
|
|
||||||
//! all the streams that belong to an **EventLoop** are managed together.
|
|
||||||
//!
|
//!
|
||||||
//! The first step is to initialise the `Host` (for accessing audio devices) and create an
|
//! The first step is to initialise the `Host`:
|
||||||
//! `EventLoop`:
|
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! use cpal::traits::HostTrait;
|
//! use cpal::traits::HostTrait;
|
||||||
//! let host = cpal::default_host();
|
//! let host = cpal::default_host();
|
||||||
//! let event_loop = host.event_loop();
|
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! Then choose a `Device`. The easiest way is to use the default input or output `Device` via the
|
//! Then choose an available `Device`. The easiest way is to use the default input or output
|
||||||
//! `default_input_device()` or `default_output_device()` functions. Alternatively you can
|
//! `Device` via the `default_input_device()` or `default_output_device()` functions. Alternatively
|
||||||
//! enumerate all the available devices with the `devices()` function. Beware that the
|
//! you can enumerate all the available devices with the `devices()` function. Beware that the
|
||||||
//! `default_*_device()` functions return an `Option` in case no device is available for that
|
//! `default_*_device()` functions return an `Option` in case no device is available for that
|
||||||
//! stream type on the system.
|
//! stream type on the system.
|
||||||
//!
|
//!
|
||||||
|
@ -56,87 +52,96 @@
|
||||||
//! .with_max_sample_rate();
|
//! .with_max_sample_rate();
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! Now that we have everything for the stream, we can create it from our event loop:
|
//! Now that we have everything for the stream, we are ready to create it from our selected device:
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use cpal::traits::{DeviceTrait, EventLoopTrait, HostTrait};
|
//! use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
|
||||||
//! # let host = cpal::default_host();
|
//! # let host = cpal::default_host();
|
||||||
//! # let event_loop = host.event_loop();
|
|
||||||
//! # let device = host.default_output_device().unwrap();
|
//! # let device = host.default_output_device().unwrap();
|
||||||
//! # let format = device.supported_output_formats().unwrap().next().unwrap().with_max_sample_rate();
|
//! # let format = device.default_output_format().unwrap();
|
||||||
//! let stream_id = event_loop.build_output_stream(&device, &format).unwrap();
|
//! let stream = device.build_output_stream(
|
||||||
|
//! &format,
|
||||||
|
//! move |data| {
|
||||||
|
//! // react to stream events and read or write stream data here.
|
||||||
|
//! },
|
||||||
|
//! move |err| {
|
||||||
|
//! // react to errors here.
|
||||||
|
//! },
|
||||||
|
//! );
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! The value returned by `build_output_stream()` is of type `StreamId` and is an identifier that
|
//! While the stream is running, the selected audio device will periodically call the data callback
|
||||||
//! will allow you to control the stream.
|
//! that was passed to the function. The callback is passed an instance of type `StreamData` that
|
||||||
|
//! represents the data that must be read from or written to. The inner `UnknownTypeOutputBuffer`
|
||||||
|
//! can be one of `I16`, `U16` or `F32` depending on the format that was passed to
|
||||||
|
//! `build_output_stream`.
|
||||||
//!
|
//!
|
||||||
//! Now we must start the stream. This is done with the `play_stream()` method on the event loop.
|
//! > **Note**: Creating and running a stream will *not* block the thread. On modern platforms, the
|
||||||
//!
|
//! > given callback is called by a dedicated, high-priority thread responsible for delivering
|
||||||
//! ```no_run
|
//! > audio data to the system's audio device in a timely manner. On older platforms that only
|
||||||
//! # use cpal::traits::{EventLoopTrait, HostTrait};
|
//! > provide a blocking API (e.g. ALSA), CPAL will create a thread in order to consistently
|
||||||
//! # let host = cpal::default_host();
|
//! > provide non-blocking behaviour. *If this is an issue for your platform or design, please
|
||||||
//! # let event_loop = host.event_loop();
|
//! > share your issue and use-case with the CPAL team on the github issue tracker for
|
||||||
//! # let stream_id = unimplemented!();
|
//! > consideration.*
|
||||||
//! event_loop.play_stream(stream_id).expect("failed to play_stream");
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! Now everything is ready! We call `run()` on the `event_loop` to begin processing.
|
|
||||||
//!
|
|
||||||
//! ```no_run
|
|
||||||
//! # use cpal::traits::{EventLoopTrait, HostTrait};
|
|
||||||
//! # let host = cpal::default_host();
|
|
||||||
//! # let event_loop = host.event_loop();
|
|
||||||
//! event_loop.run(move |_stream_id, _stream_result| {
|
|
||||||
//! // react to stream events and read or write stream data 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 stream ID and an instance of type
|
|
||||||
//! `StreamData` that represents the data that must be read from or written to. The inner
|
|
||||||
//! `UnknownTypeOutputBuffer` can be one of `I16`, `U16` or `F32` depending on the format that was
|
|
||||||
//! passed to `build_output_stream`.
|
|
||||||
//!
|
//!
|
||||||
//! In this example, we simply fill the given output buffer with zeroes.
|
//! In this example, we simply fill the given output buffer with zeroes.
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use cpal::{StreamData, UnknownTypeOutputBuffer};
|
//! use cpal::{StreamData, UnknownTypeOutputBuffer};
|
||||||
//! use cpal::traits::{EventLoopTrait, HostTrait};
|
//! use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
|
||||||
//! # let host = cpal::default_host();
|
//! # let host = cpal::default_host();
|
||||||
//! # let event_loop = host.event_loop();
|
//! # let device = host.default_output_device().unwrap();
|
||||||
//! event_loop.run(move |stream_id, stream_result| {
|
//! # let format = device.default_output_format().unwrap();
|
||||||
//! let stream_data = match stream_result {
|
//! let stream = device.build_output_stream(
|
||||||
//! Ok(data) => data,
|
//! &format,
|
||||||
//! Err(err) => {
|
//! move |data| {
|
||||||
//! eprintln!("an error occurred on stream {:?}: {}", stream_id, err);
|
//! match data {
|
||||||
//! return;
|
//! StreamData::Output { buffer: UnknownTypeOutputBuffer::U16(mut buffer) } => {
|
||||||
|
//! for elem in buffer.iter_mut() {
|
||||||
|
//! *elem = u16::max_value() / 2;
|
||||||
|
//! }
|
||||||
|
//! },
|
||||||
|
//! StreamData::Output { buffer: UnknownTypeOutputBuffer::I16(mut buffer) } => {
|
||||||
|
//! for elem in buffer.iter_mut() {
|
||||||
|
//! *elem = 0;
|
||||||
|
//! }
|
||||||
|
//! },
|
||||||
|
//! StreamData::Output { buffer: UnknownTypeOutputBuffer::F32(mut buffer) } => {
|
||||||
|
//! for elem in buffer.iter_mut() {
|
||||||
|
//! *elem = 0.0;
|
||||||
|
//! }
|
||||||
|
//! },
|
||||||
|
//! _ => (),
|
||||||
//! }
|
//! }
|
||||||
//! _ => return,
|
//! },
|
||||||
//! };
|
//! move |err| {
|
||||||
//!
|
//! eprintln!("an error occurred on the output audio stream: {}", err);
|
||||||
//! match stream_data {
|
//! },
|
||||||
//! StreamData::Output { buffer: UnknownTypeOutputBuffer::U16(mut buffer) } => {
|
//! );
|
||||||
//! for elem in buffer.iter_mut() {
|
|
||||||
//! *elem = u16::max_value() / 2;
|
|
||||||
//! }
|
|
||||||
//! },
|
|
||||||
//! StreamData::Output { buffer: UnknownTypeOutputBuffer::I16(mut buffer) } => {
|
|
||||||
//! for elem in buffer.iter_mut() {
|
|
||||||
//! *elem = 0;
|
|
||||||
//! }
|
|
||||||
//! },
|
|
||||||
//! StreamData::Output { buffer: UnknownTypeOutputBuffer::F32(mut buffer) } => {
|
|
||||||
//! for elem in buffer.iter_mut() {
|
|
||||||
//! *elem = 0.0;
|
|
||||||
//! }
|
|
||||||
//! },
|
|
||||||
//! _ => (),
|
|
||||||
//! }
|
|
||||||
//! });
|
|
||||||
//! ```
|
//! ```
|
||||||
|
//!
|
||||||
|
//! Not all platforms automatically run the stream upon creation. To ensure the stream has started,
|
||||||
|
//! we can use `Stream::play`.
|
||||||
|
//!
|
||||||
|
//! ```no_run
|
||||||
|
//! # use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
|
||||||
|
//! # let host = cpal::default_host();
|
||||||
|
//! # let device = host.default_output_device().unwrap();
|
||||||
|
//! # let format = device.default_output_format().unwrap();
|
||||||
|
//! # let stream = device.build_output_stream(&format, move |_data| {}, move |_err| {}).unwrap();
|
||||||
|
//! stream.play().unwrap();
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! Some devices support pausing the audio stream. This can be useful for saving energy in moments
|
||||||
|
//! of silence.
|
||||||
|
//!
|
||||||
|
//! ```no_run
|
||||||
|
//! # use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
|
||||||
|
//! # let host = cpal::default_host();
|
||||||
|
//! # let device = host.default_output_device().unwrap();
|
||||||
|
//! # let format = device.default_output_format().unwrap();
|
||||||
|
//! # let stream = device.build_output_stream(&format, move |_data| {}, move |_err| {}).unwrap();
|
||||||
|
//! stream.pause().unwrap();
|
||||||
|
|
||||||
#![recursion_limit = "512"]
|
#![recursion_limit = "512"]
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,16 @@ pub trait DeviceTrait {
|
||||||
|
|
||||||
/// A stream created from `Device`, with methods to control playback.
|
/// A stream created from `Device`, with methods to control playback.
|
||||||
pub trait StreamTrait {
|
pub trait StreamTrait {
|
||||||
|
/// Run the stream.
|
||||||
|
///
|
||||||
|
/// Note: Not all platforms automatically run the stream upon creation, so it is important to
|
||||||
|
/// call `play` after creation if it is expected that the stream should run immediately.
|
||||||
fn play(&self) -> Result<(), PlayStreamError>;
|
fn play(&self) -> Result<(), PlayStreamError>;
|
||||||
|
|
||||||
|
/// Some devices support pausing the audio stream. This can be useful for saving energy in
|
||||||
|
/// moments of silence.
|
||||||
|
///
|
||||||
|
/// Note: Not all devices support suspending the stream at the hardware level. This method may
|
||||||
|
/// fail in these cases.
|
||||||
fn pause(&self) -> Result<(), PauseStreamError>;
|
fn pause(&self) -> Result<(), PauseStreamError>;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue