Skip to content

Commit

Permalink
refactor: update decoder initialization to use try_from API in tests …
Browse files Browse the repository at this point in the history
…and examples

Use Decoder::try_from() instead of Decoder::new(). This new API is the preferre
way to decode files as it automatically:

- Wraps files in BufReader for better performance
- Sets file length from metadata for improved seeking
- Enables seeking by default

The functionality remains the same but uses the more optimized path.
  • Loading branch information
roderickvd committed Feb 11, 2025
1 parent 60b443f commit 001d8df
Show file tree
Hide file tree
Showing 17 changed files with 27 additions and 48 deletions.
5 changes: 2 additions & 3 deletions examples/automatic_gain_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ 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;
Expand All @@ -13,8 +12,8 @@ fn main() -> Result<(), Box<dyn Error>> {
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")?);
let source = Decoder::new(file)?;
let file = File::open("assets/music.flac")?;
let source = Decoder::try_from(file)?;

// Apply automatic gain control to the source
let agc_source = source.automatic_gain_control(1.0, 4.0, 0.005, 5.0);
Expand Down
3 changes: 1 addition & 2 deletions examples/callback_on_end.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::error::Error;
use std::io::BufReader;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;

Expand All @@ -8,7 +7,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let sink = rodio::Sink::connect_new(&stream_handle.mixer());

let file = std::fs::File::open("assets/music.wav")?;
sink.append(rodio::Decoder::new(BufReader::new(file))?);
sink.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 Down
3 changes: 1 addition & 2 deletions examples/into_file.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use rodio::{output_to_wav, Source};
use std::error::Error;
use std::io::BufReader;

/// Converts mp3 file to a wav file.
/// This example does not use any audio devices
/// and can be used in build configurations without `cpal` feature enabled.
fn main() -> Result<(), Box<dyn Error>> {
let file = std::fs::File::open("assets/music.mp3")?;
let mut audio = rodio::Decoder::new(BufReader::new(file))?
let mut audio = rodio::Decoder::try_from(file)?
.automatic_gain_control(1.0, 4.0, 0.005, 3.0)
.speed(0.8);

Expand Down
3 changes: 1 addition & 2 deletions examples/music_flac.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use std::error::Error;
use std::io::BufReader;

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")?;
sink.append(rodio::Decoder::new(BufReader::new(file))?);
sink.append(rodio::Decoder::try_from(file)?);

sink.sleep_until_end();

Expand Down
3 changes: 1 addition & 2 deletions examples/music_m4a.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use std::error::Error;
use std::io::BufReader;

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")?;
sink.append(rodio::Decoder::new(BufReader::new(file))?);
sink.append(rodio::Decoder::try_from(file)?);

sink.sleep_until_end();

Expand Down
3 changes: 1 addition & 2 deletions examples/music_mp3.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use std::error::Error;
use std::io::BufReader;

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")?;
sink.append(rodio::Decoder::new(BufReader::new(file))?);
sink.append(rodio::Decoder::try_from(file)?);

sink.sleep_until_end();

Expand Down
3 changes: 1 addition & 2 deletions examples/music_ogg.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use std::error::Error;
use std::io::BufReader;

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")?;
sink.append(rodio::Decoder::new(BufReader::new(file))?);
sink.append(rodio::Decoder::try_from(file)?);

sink.sleep_until_end();

Expand Down
3 changes: 1 addition & 2 deletions examples/music_wav.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use std::error::Error;
use std::io::BufReader;

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")?;
sink.append(rodio::Decoder::new(BufReader::new(file))?);
sink.append(rodio::Decoder::try_from(file)?);

sink.sleep_until_end();

Expand Down
3 changes: 1 addition & 2 deletions examples/reverb.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use rodio::Source;
use std::error::Error;
use std::io::BufReader;
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 file = std::fs::File::open("assets/music.ogg")?;
let source = rodio::Decoder::new(BufReader::new(file))?;
let source = rodio::Decoder::try_from(file)?;
let with_reverb = source.buffered().reverb(Duration::from_millis(40), 0.7);
sink.append(with_reverb);

Expand Down
3 changes: 1 addition & 2 deletions examples/seek_mp3.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use std::error::Error;
use std::io::BufReader;
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 file = std::fs::File::open("assets/music.mp3")?;
sink.append(rodio::Decoder::new(BufReader::new(file))?);
sink.append(rodio::Decoder::try_from(file)?);

std::thread::sleep(std::time::Duration::from_secs(2));
sink.try_seek(Duration::from_secs(0))?;
Expand Down
3 changes: 1 addition & 2 deletions examples/spatial.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::error::Error;
use std::io::BufReader;
use std::thread;
use std::time::Duration;

Expand Down Expand Up @@ -30,7 +29,7 @@ fn main() -> Result<(), Box<dyn Error>> {
);

let file = std::fs::File::open("assets/music.ogg")?;
let source = rodio::Decoder::new(BufReader::new(file))?
let source = rodio::Decoder::try_from(file)?
.repeat_infinite()
.take_duration(total_duration);
sink.append(source);
Expand Down
3 changes: 1 addition & 2 deletions examples/stereo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
use rodio::Source;
use std::error::Error;
use std::io::BufReader;

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/RL.ogg")?;
sink.append(rodio::Decoder::new(BufReader::new(file))?.amplify(0.2));
sink.append(rodio::Decoder::try_from(file)?.amplify(0.2));

sink.sleep_until_end();

Expand Down
9 changes: 3 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
//!
//! ```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.
Expand All @@ -26,9 +25,9 @@
//! .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());
//! let file = File::open("examples/music.ogg").unwrap();
//! // Decode that sound file into a source
//! let source = Decoder::new(file).unwrap();
//! let source = Decoder::try_from(file).unwrap();
//! // Play the sound directly on the device
//! stream_handle.mixer().add(source.convert_samples());
//!
Expand Down Expand Up @@ -68,10 +67,8 @@
//! 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::{OutputStream, Sink};
//! use rodio::source::{SineWave, Source};
//!
//! // _stream must live as long as the sink
Expand Down
5 changes: 2 additions & 3 deletions src/source/speed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,16 @@
//!
//! ```no_run
//!# use std::fs::File;
//!# use std::io::BufReader;
//!# use rodio::{Decoder, Sink, OutputStream, source::{Source, SineWave}};
//!
//! // Get an output stream handle to the default physical sound device.
//! // Note that no sound will be played if the _stream 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());
//! let file = File::open("examples/music.ogg").unwrap();
//! // Decode that sound file into a source
//! let source = Decoder::new(file).unwrap();
//! let source = Decoder::try_from(file).unwrap();
//! // Play the sound directly on the device 2x faster
//! stream_handle.mixer().add(source.convert_samples().speed(2.0));
//! std::thread::sleep(std::time::Duration::from_secs(5));
Expand Down
6 changes: 2 additions & 4 deletions tests/flac_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ use std::time::Duration;
#[cfg(any(feature = "flac", feature = "symphonia-flac"))]
#[test]
fn test_flac_encodings() {
use std::io::BufReader;

// 16 bit FLAC file exported from Audacity (2 channels, compression level 5)
let file = std::fs::File::open("assets/audacity16bit_level5.flac").unwrap();
let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap();
let mut decoder = rodio::Decoder::try_from(file).unwrap();

// File is not just silence
assert!(!decoder.all(|x| x.is_zero()));
Expand All @@ -23,7 +21,7 @@ fn test_flac_encodings() {
// 24 bit FLAC file exported from Audacity (2 channels, various compression levels)
for level in &[0, 5, 8] {
let file = std::fs::File::open(format!("assets/audacity24bit_level{level}.flac")).unwrap();
let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap();
let mut decoder = rodio::Decoder::try_from(file).unwrap();
assert!(!decoder.all(|x| x.is_zero()));
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
assert_eq!(decoder.total_duration(), Some(Duration::from_secs(3)));
Expand Down
3 changes: 1 addition & 2 deletions tests/mp4a_test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![cfg(all(feature = "symphonia-aac", feature = "symphonia-isomp4"))]
use std::io::BufReader;

use rodio::Sample;

Expand All @@ -11,6 +10,6 @@ fn test_mp4a_encodings() {
// Licensed under Creative Commons: By Attribution 3.0
// http://creativecommons.org/licenses/by/3.0/
let file = std::fs::File::open("assets/monkeys.mp4a").unwrap();
let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap();
let mut decoder = rodio::Decoder::try_from(file).unwrap();
assert!(!decoder.all(|x| x.is_zero())); // Assert not all zeros
}
14 changes: 6 additions & 8 deletions tests/wav_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,33 @@ use rodio::Sample;
#[cfg(feature = "wav")]
#[test]
fn test_wav_encodings() {
use std::io::BufReader;

// 16 bit wav file exported from Audacity (1 channel)
let file = std::fs::File::open("assets/audacity16bit.wav").unwrap();
let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap();
let mut decoder = rodio::Decoder::try_from(file).unwrap();
assert!(!decoder.all(|x| x.is_zero())); // Assert not all zeros

// 16 bit wav file exported from LMMS (2 channels)
let file = std::fs::File::open("assets/lmms16bit.wav").unwrap();
let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap();
let mut decoder = rodio::Decoder::try_from(file).unwrap();
assert!(!decoder.all(|x| x.is_zero()));

// 24 bit wav file exported from LMMS (2 channels)
let file = std::fs::File::open("assets/lmms24bit.wav").unwrap();
let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap();
let mut decoder = rodio::Decoder::try_from(file).unwrap();
assert!(!decoder.all(|x| x.is_zero()));

// 32 bit wav file exported from Audacity (1 channel)
let file = std::fs::File::open("assets/audacity32bit.wav").unwrap();
let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap();
let mut decoder = rodio::Decoder::try_from(file).unwrap();
assert!(!decoder.all(|x| x.is_zero()));

// 32 bit wav file exported from LMMS (2 channels)
let file = std::fs::File::open("assets/lmms32bit.wav").unwrap();
let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap();
let mut decoder = rodio::Decoder::try_from(file).unwrap();
assert!(!decoder.all(|x| x.is_zero()));

// 32 bit signed integer wav file exported from Audacity (1 channel).
let file = std::fs::File::open("assets/audacity32bit_int.wav").unwrap();
let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap();
let mut decoder = rodio::Decoder::try_from(file).unwrap();
assert!(!decoder.all(|x| x.is_zero()));
}

0 comments on commit 001d8df

Please sign in to comment.