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
11 changes: 5 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: CI
on:
pull_request:
push:
branches: [ main, master ]
branches: [main, master]

env:
RUSTFLAGS: "-C debuginfo=0 -D warnings"
Expand All @@ -18,8 +18,8 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ macos-latest, windows-latest, ubuntu-latest ]
toolchain: [ stable, beta, nightly ]
os: [macos-latest, windows-latest, ubuntu-latest]
toolchain: [stable, beta, nightly]
include:
- os: macos-latest
MACOS: true
Expand Down Expand Up @@ -49,6 +49,5 @@ jobs:
# `cargo test` does not check benchmarks and `cargo test --all-targets` excludes
# documentation tests. Therefore, we need an additional docs test command here.
- run: cargo test --doc
# Check minimal build. `tests/seek.rs` fails if there are no decoders at all,
# adding one to make the tests check pass.
- run: cargo check --tests --lib --no-default-features --features mp3
# Check minimal build.
- run: cargo check --tests --lib --no-default-features
77 changes: 72 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ minimp3_fixed = { version = "0.5.4", optional = true }
symphonia = { version = "0.5.4", optional = true, default-features = false }
crossbeam-channel = { version = "0.5.15", optional = true }

rand = { version = "0.9.0", features = ["small_rng", "os_rng"], optional = true }
rand = { version = "0.9.0", features = [
"small_rng",
"os_rng",
], optional = true }
tracing = { version = "0.1.40", optional = true }

atomic_float = { version = "1.1.0", optional = true }
Expand Down Expand Up @@ -72,27 +75,91 @@ divan = "0.1.14"
[[bench]]
name = "effects"
harness = false
required-features = ["wav"]

[[bench]]
name = "conversions"
harness = false
required-features = ["wav"]

[[bench]]
name = "resampler"
harness = false
required-features = ["wav"]

[[bench]]
name = "pipeline"
harness = false
required-features = ["wav"]

[[example]]
name = "automatic_gain_control"
required-features = ["playback", "flac"]

[[example]]
name = "basic"
required-features = ["playback", "vorbis"]

[[example]]
name = "callback_on_end"
required-features = ["playback", "wav"]

[[example]]
name = "custom_config"
required-features = ["playback", "wav"]

[[example]]
name = "error_callback"
required-features = ["playback"]

[[example]]
name = "into_file"
required-features = ["mp3", "wav"]

[[example]]
name = "low_pass"
required-features = ["playback", "wav"]

[[example]]
name = "mix_multiple_sources"
required-features = ["playback"]

[[example]]
name = "music_m4a"
required-features = ["symphonia-isomp4", "symphonia-aac"]
required-features = ["playback", "symphonia-isomp4", "symphonia-aac"]

[[example]]
name = "music_mp3"
required-features = ["playback", "mp3"]

[[example]]
name = "music_ogg"
required-features = ["playback", "vorbis"]

[[example]]
name = "music_wav"
required-features = ["playback", "wav"]

[[example]]
name = "noise_generator"
required-features = ["noise"]
required-features = ["playback", "noise"]

[[example]]
name = "into_file"
required-features = ["wav", "mp3"]
name = "reverb"
required-features = ["playback", "vorbis"]

[[example]]
name = "seek_mp3"
required-features = ["playback", "mp3"]

[[example]]
name = "signal_generator"
required-features = ["playback"]

[[example]]
name = "spatial"
required-features = ["playback", "vorbis"]

[[example]]
name = "stereo"
required-features = ["playback", "vorbis"]
7 changes: 0 additions & 7 deletions examples/noise_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

use std::error::Error;

#[cfg(feature = "noise")]
fn main() -> Result<(), Box<dyn Error>> {
use rodio::source::{pink, white, Source};
use std::thread;
Expand All @@ -29,9 +28,3 @@ fn main() -> Result<(), Box<dyn Error>> {

Ok(())
}

#[cfg(not(feature = "noise"))]
fn main() {
println!("rodio has not been compiled with noise sources, use `--features noise` to enable this feature.");
println!("Exiting...");
}
13 changes: 13 additions & 0 deletions src/decoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,14 @@ enum DecoderImpl<R: Read + Seek> {
Mp3(mp3::Mp3Decoder<R>),
#[cfg(feature = "symphonia")]
Symphonia(symphonia::SymphoniaDecoder, PhantomData<R>),
// This variant is here just to satisfy the compiler when there are no decoders enabled.
// It is unreachable and should never be constructed.
#[allow(dead_code)]
None(Unreachable, PhantomData<R>),
}

enum Unreachable {}

impl<R: Read + Seek> DecoderImpl<R> {
#[inline]
fn next(&mut self) -> Option<Sample> {
Expand All @@ -135,6 +141,7 @@ impl<R: Read + Seek> DecoderImpl<R> {
DecoderImpl::Mp3(source) => source.next(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source, PhantomData) => source.next(),
DecoderImpl::None(_, _) => unreachable!(),
}
}

Expand All @@ -151,6 +158,7 @@ impl<R: Read + Seek> DecoderImpl<R> {
DecoderImpl::Mp3(source) => source.size_hint(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source, PhantomData) => source.size_hint(),
DecoderImpl::None(_, _) => unreachable!(),
}
}

Expand All @@ -167,6 +175,7 @@ impl<R: Read + Seek> DecoderImpl<R> {
DecoderImpl::Mp3(source) => source.current_span_len(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source, PhantomData) => source.current_span_len(),
DecoderImpl::None(_, _) => unreachable!(),
}
}

Expand All @@ -183,6 +192,7 @@ impl<R: Read + Seek> DecoderImpl<R> {
DecoderImpl::Mp3(source) => source.channels(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source, PhantomData) => source.channels(),
DecoderImpl::None(_, _) => unreachable!(),
}
}

Expand All @@ -199,6 +209,7 @@ impl<R: Read + Seek> DecoderImpl<R> {
DecoderImpl::Mp3(source) => source.sample_rate(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source, PhantomData) => source.sample_rate(),
DecoderImpl::None(_, _) => unreachable!(),
}
}

Expand All @@ -221,6 +232,7 @@ impl<R: Read + Seek> DecoderImpl<R> {
DecoderImpl::Mp3(source) => source.total_duration(),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source, PhantomData) => source.total_duration(),
DecoderImpl::None(_, _) => unreachable!(),
}
}

Expand All @@ -237,6 +249,7 @@ impl<R: Read + Seek> DecoderImpl<R> {
DecoderImpl::Mp3(source) => source.try_seek(pos),
#[cfg(feature = "symphonia")]
DecoderImpl::Symphonia(source, PhantomData) => source.try_seek(pos),
DecoderImpl::None(_, _) => unreachable!(),
}
}
}
Expand Down
22 changes: 17 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
//!
//! Here is a complete example of how you would play an audio file:
//!
//! ```no_run
#![cfg_attr(not(feature = "playback"), doc = "```ignore")]
#![cfg_attr(feature = "playback", doc = "```no_run")]
//! use std::fs::File;
//! use rodio::{Decoder, OutputStream, source::Source};
//!
Expand All @@ -34,7 +35,8 @@
//! ```
//!
//! [`rodio::play()`](crate::play) helps to simplify the above
//! ```no_run
#![cfg_attr(not(feature = "playback"), doc = "```ignore")]
#![cfg_attr(feature = "playback", doc = "```no_run")]
//! use std::fs::File;
//! use std::io::BufReader;
//! use rodio::{Decoder, OutputStream, source::Source};
Expand Down Expand Up @@ -63,7 +65,8 @@
//! To play a soung Create a [`Sink`] connect it to the output stream,
//! and [`.append()`](Sink::append) your sound to it.
//!
//! ```no_run
#![cfg_attr(not(feature = "playback"), doc = "```ignore")]
#![cfg_attr(feature = "playback", doc = "```no_run")]
//! use std::time::Duration;
//! use rodio::{OutputStream, Sink};
//! use rodio::source::{SineWave, Source};
Expand Down Expand Up @@ -96,7 +99,8 @@
//!
//! Example:
//!
//! ```
#![cfg_attr(not(feature = "playback"), doc = "```ignore")]
#![cfg_attr(feature = "playback", doc = "```")]
//! use rodio::Source;
//! use std::time::Duration;
//!
Expand Down Expand Up @@ -147,7 +151,15 @@
//! 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_attr(
any(test, not(feature = "playback")),
deny(missing_docs),
allow(dead_code),
allow(unused_imports),
allow(unused_variables),
allow(unreachable_code)
)]

#[cfg(feature = "playback")]
pub use cpal::{
self, traits::DeviceTrait, Device, Devices, DevicesError, InputDevices, OutputDevices,
Expand Down
6 changes: 4 additions & 2 deletions src/source/speed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
//! To speed up a source from sink all you need to do is call the `set_speed(factor: f32)` function
//! For example, here is how you speed up your sound by using sink or playing raw:
//!
//! ```no_run
#![cfg_attr(not(feature = "playback"), doc = "```ignore")]
#![cfg_attr(feature = "playback", doc = "```no_run")]
//!# use std::fs::File;
//!# use rodio::{Decoder, Sink, OutputStream, source::{Source, SineWave}};
//!
Expand All @@ -28,7 +29,8 @@
//! std::thread::sleep(std::time::Duration::from_secs(5));
//! ```
//! Here is how you would do it using the sink:
//!```no_run
#![cfg_attr(not(feature = "playback"), doc = "```ignore")]
#![cfg_attr(feature = "playback", doc = "```no_run")]
//! use rodio::source::{Source, SineWave};
//! let source = SineWave::new(440.0)
//! .take_duration(std::time::Duration::from_secs_f32(20.25))
Expand Down
7 changes: 2 additions & 5 deletions tests/flac_test.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
#[cfg(any(feature = "flac", feature = "symphonia-flac"))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could handle these the same way as with the examples. I think this is fine though. Examples should be as simple as possible so not having conditional comp in there is nice. These tests are not meant to help users so having them look a little more daunting is fine.

use rodio::Source;
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
#[cfg(any(feature = "flac", feature = "symphonia-flac"))]
use std::time::Duration;

#[cfg(any(feature = "flac", feature = "symphonia-flac"))]
Expand All @@ -12,16 +12,13 @@ fn test_flac_encodings() {

// File is not just silence
assert!(decoder.any(|x| x != 0.0));
// Symphonia does not expose functionality to get the duration so this check must be disabled
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
assert_eq!(decoder.total_duration(), Some(Duration::from_secs(3))); // duration is calculated correctly

// 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::try_from(file).unwrap();
assert!(!decoder.all(|x| x != 0.0));
#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))]
assert_eq!(decoder.total_duration(), Some(Duration::from_secs(3)));
}
}
Loading