-
Notifications
You must be signed in to change notification settings - Fork 302
Expand file tree
/
Copy pathlib.rs
More file actions
186 lines (182 loc) · 7.52 KB
/
lib.rs
File metadata and controls
186 lines (182 loc) · 7.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//! Audio playback library.
//!
//! The main concept of this library is the [`Source`] trait, which
//! represents a sound (streaming or not). In order to play a sound, there are three steps:
//!
//! - Get an output stream handle to a physical device. For example, get a stream to the system's
//! default sound device with [`OutputStreamBuilder::open_default_stream()`].
//! - Create an object that represents the streaming sound. It can be a sine wave, a buffer, a
//! [`decoder`], etc. or even your own type that implements the [`Source`] trait.
//! - Add the source to the output stream using [`OutputStream::mixer()`](OutputStream::mixer)
//! on the output stream handle.
//!
//! The output stream expects the sources to produce [`f32`]s. In case the output sample format
//! is different use [`.convert_samples()`](Source::convert_samples) to adapt them.
//!
//! Here is a complete example of how you would play an audio file:
//!
//! ```no_run
//! use std::fs::File;
//! use std::io::BufReader;
//! use rodio::{Decoder, OutputStream, source::Source};
//!
//! // Get an output stream handle to the default physical sound device.
//! // Note that the playback stops when the stream_handle is dropped.//!
//! let stream_handle = rodio::OutputStreamBuilder::open_default_stream()
//! .expect("open default audio stream");
//! let sink = rodio::Sink::connect_new(&stream_handle.mixer());
//! // Load a sound from a file, using a path relative to Cargo.toml
//! let file = BufReader::new(File::open("examples/music.ogg").unwrap());
//! // Decode that sound file into a source
//! let source = Decoder::new(file).unwrap();
//! // Play the sound directly on the device
//! stream_handle.mixer().add(source.convert_samples());
//!
//! // The sound plays in a separate audio thread,
//! // so we need to keep the main thread alive while it's playing.
//! std::thread::sleep(std::time::Duration::from_secs(5));
//! ```
//!
//! [rodio::play()] helps to simplify the above
//! ```no_run
//! use std::fs::File;
//! use std::io::BufReader;
//! use rodio::{Decoder, OutputStream, source::Source};
//!
//! // Get an output stream handle to the default physical sound device.
//! // Note that the playback stops when the stream_handle is dropped.
//! let stream_handle = rodio::OutputStreamBuilder::open_default_stream()
//! .expect("open default audio stream");
//!
//! // Load a sound from a file, using a path relative to Cargo.toml
//! let file = BufReader::new(File::open("examples/music.ogg").unwrap());
//! rodio::play(&stream_handle.mixer(), file).unwrap();
//!
//! // The sound plays in a separate audio thread,
//! // so we need to keep the main thread alive while it's playing.
//! std::thread::sleep(std::time::Duration::from_secs(5));
//! ```
//!
//!
//! ## Sink
//!
//! In order to make it easier to control the playback, the rodio library also provides a type
//! named [`Sink`] which represents an audio track. [`Sink`] plays its input sources sequentially,
//! one after another. To play sounds in simultaneously in parallel, use [`mixer::Mixer`] instead.
//!
//! To play a soung Create a [`Sink`] connect it to the output stream,
//! and [`.append()`](Sink::append) your sound to it.
//!
//! ```no_run
//! use std::fs::File;
//! use std::io::BufReader;
//! use std::time::Duration;
//! use rodio::{Decoder, OutputStream, Sink};
//! use rodio::source::{SineWave, Source};
//!
//! // _stream must live as long as the sink
//! let stream_handle = rodio::OutputStreamBuilder::open_default_stream()
//! .expect("open default audio stream");
//! let sink = rodio::Sink::connect_new(&stream_handle.mixer());
//!
//! // Add a dummy source of the sake of the example.
//! let source = SineWave::new(440.0).take_duration(Duration::from_secs_f32(0.25)).amplify(0.20);
//! sink.append(source);
//!
//! // The sound plays in a separate thread. This call will block the current thread until the sink
//! // has finished playing all its queued sounds.
//! sink.sleep_until_end();
//! ```
//!
//! The [`append`](Sink::append) method will add the sound at the end of the
//! sink. It will be played when all the previous sounds have been played. If you want multiple
//! sounds to play simultaneously, you should create multiple [`Sink`]s.
//!
//! The [`Sink`] type also provides utilities such as playing/pausing or controlling the volume.
//!
//! **Please note that the [`Sink`] requires the [`OutputStream`], make sure that the OutputStream is not dropped before the sink.**
//!
//! ## Filters
//!
//! The [`Source`] trait provides various filters, similar to the standard [`Iterator`] trait.
//!
//! Example:
//!
//! ```
//! use rodio::Source;
//! use std::time::Duration;
//!
//! // Repeats the first five seconds of the sound forever.
//! # let source = rodio::source::SineWave::new(440.0);
//! let source = source.take_duration(Duration::from_secs(5)).repeat_infinite();
//! ```
//!
//! ## Alternative Decoder Backends
//!
//! [Symphonia](https://github.com/pdeljanov/Symphonia) is an alternative decoder library that can be used in place
//! of many of the default backends.
//! Currently, the main benefit is that Symphonia is the only backend that supports M4A and AAC,
//! but it may be used to implement additional optional functionality in the future.
//!
//! To use, enable either the `symphonia-all` feature to enable all Symphonia codecs
//! or enable specific codecs using one of the `symphonia-{codec name}` features.
//! If you enable one or more of the Symphonia codecs, you may want to set `default-features = false` in order
//! to avoid adding extra crates to your binary.
//! See the [available feature flags](https://docs.rs/crate/rodio/latest/features) for all options.
//!
//! ## Optional Features
//!
//! Rodio provides several optional features that are guarded with feature gates.
//!
//! ### Feature "tracing"
//!
//! The "tracing" feature replaces the print to stderr when a stream error happens with a
//! recording an error event with tracing.
//!
//! ### Feature "Noise"
//!
//! The "noise" feature adds support for white and pink noise sources. This feature requires the
//! "rand" crate.
//!
//! ## How it works under the hood
//!
//! Rodio spawns a background thread that is dedicated to reading from the sources and sending
//! the output to the device. Whenever you give up ownership of a [`Source`] in order to play it,
//! it is sent to this background thread where it will be read by rodio.
//!
//! All the sounds are mixed together by rodio before being sent to the operating system or the
//! hardware. Therefore, there is no restriction on the number of sounds that play simultaneously or
//! on the number of sinks that can be created (except for the fact that creating too many will slow
//! down your program).
#![cfg_attr(test, deny(missing_docs))]
#[cfg(feature = "playback")]
pub use cpal::{
self, traits::DeviceTrait, Device, Devices, DevicesError, InputDevices, OutputDevices,
SupportedStreamConfig,
};
mod channel_bitmask;
mod common;
mod conversions;
mod sink;
mod spatial_sink;
#[cfg(feature = "playback")]
mod stream;
#[cfg(feature = "wav")]
mod wav_output;
pub mod buffer;
pub mod decoder;
pub mod mixer;
pub mod queue;
pub mod source;
pub mod static_buffer;
pub use crate::channel_bitmask::ChannelBitmask;
pub use crate::common::{ChannelCount, SampleRate};
pub use crate::conversions::Sample;
pub use crate::decoder::Decoder;
pub use crate::sink::Sink;
pub use crate::source::Source;
pub use crate::spatial_sink::SpatialSink;
#[cfg(feature = "playback")]
pub use crate::stream::{play, OutputStream, OutputStreamBuilder, PlayError, StreamError};
#[cfg(feature = "wav")]
pub use crate::wav_output::output_to_wav;