Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed `Zero::current_span_len` returning remaining samples instead of span length.

### Changed
- Breaking: _Sink_ terms are replaced with _Player_ and _Stream_ terms replaced
with _Sink_. This is a simple rename, functionality is identical.
- `OutputStream` is now `MixerDeviceSink` (in anticipation of future
`QueueDeviceSink`)
- `OutputStreamBuilder` is now `DeviceSinkBuilder`
- `open_stream_or_fallback` is now `open_sink_or_fallback`
- `open_default_stream` is now `open_default_sink`
- `open_stream` is now `open_mixer` (in anticipation of future `open_queue`)
- `Sink` is now `Player`
- `SpatialSink` is now `SpatialPlayer`
- `StreamError` is now `OsSinkError`
- `output_to_wav` renamed to `wav_to_file` and now takes ownership of the `Source`.
- `Blue` noise generator uses uniform instead of Gaussian noise for better performance.
- `Gaussian` noise generator has standard deviation of 0.6 for perceptual equivalence.
Expand Down Expand Up @@ -165,7 +176,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
implementation.

### Fixed
- `Sink.try_seek` now updates `controls.position` before returning. Calls to `Sink.get_pos`
- `player.try_seek` now updates `controls.position` before returning. Calls to `player.get_pos`
done immediately after a seek will now return the correct value.

### Changed
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ src/:
- Follow [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/)
- Use `rustfmt` for formatting
- Implement `Source` trait for new audio sources
- Use `Sink` for playback management
- Use `Player` for playback management

## Common Tasks

Expand Down
4 changes: 2 additions & 2 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ No changes are required.
The following Rodio *0.20* code:
```rust
let (_stream, handle) = rodio::OutputStream::try_default()?;
let sink = rodio::Sink::try_new(&handle)?;
let player = rodio::Player::try_new(&handle)?;
```
Should be written like this in Rodio *0.21*:
```rust
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(stream_handle.mixer());
let player = rodio::Player::connect_new(stream_handle.mixer());
```

The `SpatialSink` changes mirror those in `Sink` described above.
Expand Down
8 changes: 4 additions & 4 deletions examples/automatic_gain_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use std::thread;
use std::time::Duration;

fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(stream_handle.mixer());
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let player = rodio::Player::connect_new(stream_handle.mixer());

// Decode the sound file into a source
let file = File::open("assets/music.flac")?;
Expand All @@ -29,7 +29,7 @@ fn main() -> Result<(), Box<dyn Error>> {

// Add the source now equipped with automatic gain control and controlled via
// periodic_access to the sink for the playback.
sink.append(controlled);
player.append(controlled);

// After 5 seconds of playback disable automatic gain control using the
// shared AtomicBool `agc_enabled`. You could do this from another part
Expand All @@ -42,6 +42,6 @@ fn main() -> Result<(), Box<dyn Error>> {
agc_enabled.store(false, Ordering::Relaxed);

// Keep the program running until the playback is complete.
sink.sleep_until_end();
player.sleep_until_end();
Ok(())
}
14 changes: 7 additions & 7 deletions examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ use std::thread;
use std::time::Duration;

fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let mixer = stream_handle.mixer();

let beep1 = {
// Play a WAV file.
let file = std::fs::File::open("assets/beep.wav")?;
let sink = rodio::play(mixer, BufReader::new(file))?;
sink.set_volume(0.2);
sink
let player = rodio::play(mixer, BufReader::new(file))?;
player.set_volume(0.2);
player
};
println!("Started beep1");
thread::sleep(Duration::from_millis(1500));
Expand All @@ -32,9 +32,9 @@ fn main() -> Result<(), Box<dyn Error>> {
let beep3 = {
// Play an OGG file.
let file = std::fs::File::open("assets/beep3.ogg")?;
let sink = rodio::play(mixer, BufReader::new(file))?;
sink.set_volume(0.2);
sink
let player = rodio::play(mixer, BufReader::new(file))?;
player.set_volume(0.2);
player
};
println!("Started beep3");
thread::sleep(Duration::from_millis(1500));
Expand Down
10 changes: 5 additions & 5 deletions examples/callback_on_end.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;

fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(stream_handle.mixer());
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let player = rodio::Player::connect_new(stream_handle.mixer());

let file = std::fs::File::open("assets/music.wav")?;
sink.append(rodio::Decoder::try_from(file)?);
player.append(rodio::Decoder::try_from(file)?);

// lets increment a number after `music.wav` has played. We are going to use atomics
// however you could also use a `Mutex` or send a message through a `std::sync::mpsc`.
Expand All @@ -17,7 +17,7 @@ fn main() -> Result<(), Box<dyn Error>> {
// playlist_pos into the closure. That way we can still access playlist_pos
// after appending the EmptyCallback.
let playlist_pos_clone = playlist_pos.clone();
sink.append(rodio::source::EmptyCallback::new(Box::new(move || {
player.append(rodio::source::EmptyCallback::new(Box::new(move || {
println!("empty callback is now running");
playlist_pos_clone.fetch_add(1, Ordering::Relaxed);
})));
Expand All @@ -27,7 +27,7 @@ fn main() -> Result<(), Box<dyn Error>> {
"playlist position is: {}",
playlist_pos.load(Ordering::Relaxed)
);
sink.sleep_until_end();
player.sleep_until_end();
assert_eq!(playlist_pos.load(Ordering::Relaxed), 1);
println!(
"playlist position is: {}",
Expand Down
6 changes: 3 additions & 3 deletions examples/custom_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ fn main() -> Result<(), Box<dyn Error>> {
let default_device = cpal::default_host()
.default_output_device()
.ok_or("No default audio output device is found.")?;
let stream_handle = rodio::OutputStreamBuilder::from_device(default_device)?
let stream_handle = rodio::DeviceSinkBuilder::from_device(default_device)?
// No need to set all parameters explicitly here,
// the defaults were set from the device's description.
.with_buffer_size(BufferSize::Fixed(256))
.with_sample_rate(NonZero::new(48_000).unwrap())
.with_sample_format(SampleFormat::F32)
// Note that the function below still tries alternative configs if the specified one fails.
// If you need to only use the exact specified configuration,
// then use OutputStreamBuilder::open_stream() instead.
.open_stream_or_fallback()?;
// then use DeviceSinkBuilder::open_sink() instead.
.open_sink_or_fallback()?;
let mixer = stream_handle.mixer();

let wave = SineWave::new(740.0)
Expand Down
2 changes: 1 addition & 1 deletion examples/distortion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::time::Duration;

fn main() -> Result<(), Box<dyn Error>> {
// Open the default output stream and get the mixer
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let mixer = stream_handle.mixer();

// Create a sine wave source and apply distortion
Expand Down
8 changes: 4 additions & 4 deletions examples/distortion_mp3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ use std::error::Error;
use rodio::Source;

fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(stream_handle.mixer());
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let player = rodio::Player::connect_new(stream_handle.mixer());

let file = std::fs::File::open("assets/music.mp3")?;
// Apply distortion effect before appending to the sink
let source = rodio::Decoder::try_from(file)?.distortion(4.0, 0.3);
sink.append(source);
player.append(source);

sink.sleep_until_end();
player.sleep_until_end();

Ok(())
}
8 changes: 4 additions & 4 deletions examples/distortion_wav.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ use std::error::Error;
use rodio::Source;

fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(stream_handle.mixer());
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let player = rodio::Player::connect_new(stream_handle.mixer());

let file = std::fs::File::open("assets/music.wav")?;
// Apply distortion effect before appending to the sink
let source = rodio::Decoder::try_from(file)?.distortion(4.0, 0.3);
sink.append(source);
player.append(source);

sink.sleep_until_end();
player.sleep_until_end();

Ok(())
}
8 changes: 4 additions & 4 deletions examples/distortion_wav_alternate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use std::time::Duration;
use rodio::Source;

fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(stream_handle.mixer());
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let player = rodio::Player::connect_new(stream_handle.mixer());

let file = std::fs::File::open("assets/music.wav")?;
let source = rodio::Decoder::try_from(file)?;
Expand All @@ -31,7 +31,7 @@ fn main() -> Result<(), Box<dyn Error>> {
src.set_threshold(if enable { 0.3 } else { 1.0 });
});

sink.append(distorted);
player.append(distorted);

println!("Playing music.wav with alternating distortion effect...");
// Alternate the distortion effect every second for 10 seconds
Expand All @@ -43,7 +43,7 @@ fn main() -> Result<(), Box<dyn Error>> {
}

// Wait for playback to finish
sink.sleep_until_end();
player.sleep_until_end();

Ok(())
}
4 changes: 2 additions & 2 deletions examples/error_callback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn main() -> Result<(), Box<dyn Error>> {

let (tx, rx) = std::sync::mpsc::channel();

let stream_handle = rodio::OutputStreamBuilder::from_device(default_device)?
let stream_handle = rodio::DeviceSinkBuilder::from_device(default_device)?
.with_error_callback(move |err| {
// Filter for where err is an actionable error.
if matches!(
Expand All @@ -24,7 +24,7 @@ fn main() -> Result<(), Box<dyn Error>> {
}
}
})
.open_stream_or_fallback()?;
.open_sink_or_fallback()?;

let mixer = stream_handle.mixer();

Expand Down
8 changes: 4 additions & 4 deletions examples/limit_wav.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ use rodio::{source::LimitSettings, Source};
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(stream_handle.mixer());
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let player = rodio::Player::connect_new(stream_handle.mixer());

let file = std::fs::File::open("assets/music.wav")?;
let source = rodio::Decoder::try_from(file)?
.amplify(3.0)
.limit(LimitSettings::default());

sink.append(source);
player.append(source);

println!("Playing music.wav with limiting until finished...");
sink.sleep_until_end();
player.sleep_until_end();
println!("Done.");

Ok(())
Expand Down
8 changes: 4 additions & 4 deletions examples/low_pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ use std::io::BufReader;
use rodio::Source;

fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(stream_handle.mixer());
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let player = rodio::Player::connect_new(stream_handle.mixer());

let file = std::fs::File::open("assets/music.wav")?;
let decoder = rodio::Decoder::new(BufReader::new(file))?;
let source = decoder.low_pass(200);
sink.append(source);
player.append(source);

sink.sleep_until_end();
player.sleep_until_end();

Ok(())
}
2 changes: 1 addition & 1 deletion examples/microphone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let recording = input.take_duration(Duration::from_secs(5)).record();

println!("Playing the recording");
let mut output = rodio::OutputStreamBuilder::open_default_stream()?;
let mut output = rodio::DeviceSinkBuilder::open_default_sink()?;
output.mixer().add(recording);

thread::sleep(Duration::from_secs(5));
Expand Down
10 changes: 5 additions & 5 deletions examples/mix_multiple_sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ const NOTE_DURATION: Duration = Duration::from_secs(1);
const NOTE_AMPLITUDE: Float = 0.20;

fn main() -> Result<(), Box<dyn Error>> {
// Construct a dynamic controller and mixer, stream_handle, and sink.
// Construct a dynamic controller and mixer, stream_handle, and player.
let (controller, mixer) = mixer::mixer(NonZero::new(2).unwrap(), NonZero::new(44_100).unwrap());
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(stream_handle.mixer());
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let player = rodio::Player::connect_new(stream_handle.mixer());

// Create four unique sources. The frequencies used here correspond
// notes in the key of C and in octave 4: C4, or middle C on a piano,
Expand All @@ -37,10 +37,10 @@ fn main() -> Result<(), Box<dyn Error>> {
controller.add(source_a);

// Append the dynamic mixer to the sink to play a C major 6th chord.
sink.append(mixer);
player.append(mixer);

// Sleep the thread until sink is empty.
sink.sleep_until_end();
player.sleep_until_end();

Ok(())
}
8 changes: 4 additions & 4 deletions examples/music_flac.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(stream_handle.mixer());
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let player = rodio::Player::connect_new(stream_handle.mixer());

let file = std::fs::File::open("assets/music.flac")?;
sink.append(rodio::Decoder::try_from(file)?);
player.append(rodio::Decoder::try_from(file)?);

sink.sleep_until_end();
player.sleep_until_end();

Ok(())
}
8 changes: 4 additions & 4 deletions examples/music_m4a.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(stream_handle.mixer());
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let player = rodio::Player::connect_new(stream_handle.mixer());

let file = std::fs::File::open("assets/music.m4a")?;
sink.append(rodio::Decoder::try_from(file)?);
player.append(rodio::Decoder::try_from(file)?);

sink.sleep_until_end();
player.sleep_until_end();

Ok(())
}
8 changes: 4 additions & 4 deletions examples/music_mp3.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(stream_handle.mixer());
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
let player = rodio::Player::connect_new(stream_handle.mixer());

let file = std::fs::File::open("assets/music.mp3")?;
sink.append(rodio::Decoder::try_from(file)?);
player.append(rodio::Decoder::try_from(file)?);

sink.sleep_until_end();
player.sleep_until_end();

Ok(())
}
Loading