Skip to content

Commit

Permalink
Merge remote-tracking branch 'rust-audio/master' into test-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
PetrGlad committed Nov 26, 2024
2 parents 565b026 + bc8d1c7 commit b7dbe3f
Show file tree
Hide file tree
Showing 23 changed files with 595 additions and 367 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
- Output audio stream buffer size can now be adjusted.

### Changed
- Breaking: `OutputStreamBuilder` should now be used to initialize audio output stream.
- Breaking: `OutputStreamHandle` removed, use `OutputStream` and `OutputStream::mixer()` instead.
- Breaking: `DynamicMixerController` renamed to `Mixer`, `DynamicMixer` renamed to `MixerSource`.
- Breaking: `Sink::try_new` renamed to `connect_new` and does not return error anymore.
`Sink::new_idle` was renamed to `new`.

# Version 0.20.1 (2024-11-08)

### Fixed
Expand Down
17 changes: 9 additions & 8 deletions examples/automatic_gain_control.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
use rodio::source::Source;
use rodio::Decoder;
use std::error::Error;
use std::fs::File;
use std::io::BufReader;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
use std::time::Duration;

fn main() {
let (_stream, handle) = rodio::OutputStream::try_default().unwrap();
let sink = rodio::Sink::try_new(&handle).unwrap();
fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(&stream_handle.mixer());

// Decode the sound file into a source
let file = BufReader::new(File::open("assets/music.flac").unwrap());
let source = Decoder::new(file).unwrap();
let file = BufReader::new(File::open("assets/music.flac")?);
let source = Decoder::new(file)?;

// Apply automatic gain control to the source
let agc_source = source.automatic_gain_control(1.0, 4.0, 0.005, 5.0);
Expand All @@ -22,14 +23,13 @@ fn main() {
// enabled or disabled every 5 milliseconds. We must clone `agc_enabled`,
// or we would lose it when we move it into the periodic access.
let agc_enabled = Arc::new(AtomicBool::new(true));

let agc_enabled_clone = agc_enabled.clone();
let controlled = agc_source.periodic_access(Duration::from_millis(5), move |agc_source| {
agc_source.set_enabled(agc_enabled_clone.load(Ordering::Relaxed));
});

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

// After 5 seconds of playback disable automatic gain control using the
Expand All @@ -42,6 +42,7 @@ fn main() {
thread::sleep(Duration::from_secs(5));
agc_enabled.store(false, Ordering::Relaxed);

// Keep the program running until playback is complete
// Keep the program running until the playback is complete.
sink.sleep_until_end();
Ok(())
}
52 changes: 35 additions & 17 deletions examples/basic.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,46 @@
use rodio::source::SineWave;
use rodio::Source;
use std::error::Error;
use std::io::BufReader;
use std::thread;
use std::time::Duration;

fn main() {
let (_stream, stream_handle) = rodio::OutputStream::try_default().unwrap();

let file = std::fs::File::open("assets/beep.wav").unwrap();
let beep1 = stream_handle.play_once(BufReader::new(file)).unwrap();
beep1.set_volume(0.2);
#[cfg(feature = "tracing")]
use tracing;

fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
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
};
println!("Started beep1");

thread::sleep(Duration::from_millis(1500));

let file = std::fs::File::open("assets/beep2.wav").unwrap();
let beep2 = stream_handle.play_once(BufReader::new(file)).unwrap();
beep2.set_volume(0.3);
beep2.detach();
{
// Generate sine wave.
let wave = SineWave::new(740.0)
.amplify(0.2)
.take_duration(Duration::from_secs(3));
mixer.add(wave);
}
println!("Started beep2");

thread::sleep(Duration::from_millis(1500));
let file = std::fs::File::open("assets/beep3.ogg").unwrap();
let beep3 = stream_handle.play_once(file).unwrap();
beep3.set_volume(0.2);
println!("Started beep3");

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
};
println!("Started beep3");
thread::sleep(Duration::from_millis(1500));

drop(beep1);
println!("Stopped beep1");

Expand All @@ -33,4 +49,6 @@ fn main() {
println!("Stopped beep3");

thread::sleep(Duration::from_millis(1500));

Ok(())
}
35 changes: 35 additions & 0 deletions examples/custom_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use cpal::traits::HostTrait;
use cpal::{BufferSize, SampleFormat, SampleRate};
use rodio::source::SineWave;
use rodio::Source;
use std::error::Error;
use std::thread;
use std::time::Duration;

fn main() -> Result<(), Box<dyn Error>> {
// You can use any other output device that can be queried from CPAL.
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)?
// 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(SampleRate(48_000))
.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()?;
let mixer = stream_handle.mixer();

let wave = SineWave::new(740.0)
.amplify(0.1)
.take_duration(Duration::from_secs(1));
mixer.add(wave);

println!("Beep...");
thread::sleep(Duration::from_millis(1500));

Ok(())
}
13 changes: 8 additions & 5 deletions examples/mix_multiple_sources.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use rodio::mixer;
use rodio::source::{SineWave, Source};
use rodio::{dynamic_mixer, OutputStream, Sink};
use std::error::Error;
use std::time::Duration;

fn main() {
fn main() -> Result<(), Box<dyn Error>> {
// Construct a dynamic controller and mixer, stream_handle, and sink.
let (controller, mixer) = dynamic_mixer::mixer::<f32>(2, 44_100);
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let sink = Sink::try_new(&stream_handle).unwrap();
let (controller, mixer) = mixer::mixer::<f32>(2, 44_100);
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::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 Down Expand Up @@ -35,4 +36,6 @@ fn main() {

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

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

fn main() {
let (_stream, handle) = rodio::OutputStream::try_default().unwrap();
let sink = rodio::Sink::try_new(&handle).unwrap();
fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(&stream_handle.mixer());

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

sink.sleep_until_end();

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

fn main() {
let (_stream, handle) = rodio::OutputStream::try_default().unwrap();
let sink = rodio::Sink::try_new(&handle).unwrap();
fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(&stream_handle.mixer());

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

sink.sleep_until_end();

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

fn main() {
let (_stream, handle) = rodio::OutputStream::try_default().unwrap();
let sink = rodio::Sink::try_new(&handle).unwrap();
fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(&stream_handle.mixer());

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

sink.sleep_until_end();

Ok(())
}
13 changes: 8 additions & 5 deletions examples/music_ogg.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use std::error::Error;
use std::io::BufReader;

fn main() {
let (_stream, handle) = rodio::OutputStream::try_default().unwrap();
let sink = rodio::Sink::try_new(&handle).unwrap();
fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(&stream_handle.mixer());

let file = std::fs::File::open("assets/music.ogg").unwrap();
sink.append(rodio::Decoder::new(BufReader::new(file)).unwrap());
let file = std::fs::File::open("assets/music.ogg")?;
sink.append(rodio::Decoder::new(BufReader::new(file))?);

sink.sleep_until_end();

Ok(())
}
13 changes: 8 additions & 5 deletions examples/music_wav.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use std::error::Error;
use std::io::BufReader;

fn main() {
let (_stream, handle) = rodio::OutputStream::try_default().unwrap();
let sink = rodio::Sink::try_new(&handle).unwrap();
fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(&stream_handle.mixer());

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

sink.sleep_until_end();

Ok(())
}
32 changes: 16 additions & 16 deletions examples/noise_generator.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
//! Noise generator example. Use the "noise" feature to enable the noise generator sources.

use std::error::Error;

#[cfg(feature = "noise")]
fn main() {
fn main() -> Result<(), Box<dyn Error>> {
use rodio::source::{pink, white, Source};
use std::thread;
use std::time::Duration;

let (_stream, stream_handle) = rodio::OutputStream::try_default().unwrap();
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;

let noise_duration = Duration::from_millis(1000);
let interval_duration = Duration::from_millis(1500);

stream_handle
.play_raw(
white(cpal::SampleRate(48000))
.amplify(0.1)
.take_duration(noise_duration),
)
.unwrap();
stream_handle.mixer().add(
white(cpal::SampleRate(48000))
.amplify(0.1)
.take_duration(noise_duration),
);
println!("Playing white noise");

thread::sleep(interval_duration);

stream_handle
.play_raw(
pink(cpal::SampleRate(48000))
.amplify(0.1)
.take_duration(noise_duration),
)
.unwrap();
stream_handle.mixer().add(
pink(cpal::SampleRate(48000))
.amplify(0.1)
.take_duration(noise_duration),
);
println!("Playing pink noise");

thread::sleep(interval_duration);

Ok(())
}

#[cfg(not(feature = "noise"))]
Expand Down
13 changes: 8 additions & 5 deletions examples/reverb.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
use rodio::Source;
use std::error::Error;
use std::io::BufReader;
use std::time::Duration;

fn main() {
let (_stream, handle) = rodio::OutputStream::try_default().unwrap();
let sink = rodio::Sink::try_new(&handle).unwrap();
fn main() -> Result<(), Box<dyn Error>> {
let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
let sink = rodio::Sink::connect_new(&stream_handle.mixer());

let file = std::fs::File::open("assets/music.ogg").unwrap();
let source = rodio::Decoder::new(BufReader::new(file)).unwrap();
let file = std::fs::File::open("assets/music.ogg")?;
let source = rodio::Decoder::new(BufReader::new(file))?;
let with_reverb = source.buffered().reverb(Duration::from_millis(40), 0.7);
sink.append(with_reverb);

sink.sleep_until_end();

Ok(())
}
Loading

0 comments on commit b7dbe3f

Please sign in to comment.