From 18dbe8504f6f8a8204c67d49036dc20afc08c17b Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Wed, 9 Jun 2021 20:53:20 -0500 Subject: [PATCH 01/18] add symphonia decoder --- Cargo.toml | 37 ++++++--- build.rs | 13 +++ examples/music.m4a | Bin 0 -> 328787 bytes examples/music_m4a.rs | 11 +++ src/decoder/mod.rs | 135 +++++++++++++++++++++++++++++++- src/decoder/mp3.rs | 24 +++++- src/decoder/read_seek_source.rs | 37 +++++++++ src/decoder/symphonia.rs | 131 +++++++++++++++++++++++++++++++ 8 files changed, 372 insertions(+), 16 deletions(-) create mode 100644 build.rs create mode 100644 examples/music.m4a create mode 100644 examples/music_m4a.rs create mode 100644 src/decoder/read_seek_source.rs create mode 100644 src/decoder/symphonia.rs diff --git a/Cargo.toml b/Cargo.toml index 0d79dfdd..f8f0aa37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,29 +1,42 @@ [package] -name = "rodio" -version = "0.14.0" authors = ["Pierre Krieger "] -license = "MIT OR Apache-2.0" description = "Audio playback library" -keywords = ["audio", "playback", "gamedev"] -repository = "https://github.com/RustAudio/rodio" documentation = "http://docs.rs/rodio" edition = "2018" +keywords = ["audio", "playback", "gamedev"] +license = "MIT OR Apache-2.0" +name = "rodio" +repository = "https://github.com/RustAudio/rodio" +version = "0.14.0" [dependencies] +claxon = {version = "0.4.2", optional = true} cpal = "0.13" -claxon = { version = "0.4.2", optional = true } -hound = { version = "3.3.1", optional = true } -lewton = { version = "0.10", optional = true } -minimp3 = { version = "0.5.0", optional = true } +hound = {version = "3.3.1", optional = true} +lewton = {version = "0.10", optional = true} +minimp3 = {version = "0.5.0", optional = true} +symphonia = {path = "../symphonia/symphonia", optional = true, default-features = false} [features] -default = ["flac", "vorbis", "wav", "mp3"] +default = ["flac", "vorbis", "symphonia-all"] flac = ["claxon"] -vorbis = ["lewton"] -wav = ["hound"] mp3 = ["minimp3"] +symphonia-aac = ["symphonia/aac"] +symphonia-all = ["symphonia-aac", "symphonia-isomp4", "symphonia-mp3", "symphonia-wav"] +symphonia-isomp4 = ["symphonia/isomp4"] +symphonia-mp3 = ["symphonia/mp3"] +symphonia-wav = ["symphonia/wav", "symphonia/pcm"] +vorbis = ["lewton"] wasm-bindgen = ["cpal/wasm-bindgen"] +wav = ["hound"] [dev-dependencies] quickcheck = "0.9.2" + +[build-dependencies] +cfg_aliases = "0.1.1" + +[[example]] +name = "music_m4a" +required-features = ["symphonia-isomp4", "symphonia-aac"] diff --git a/build.rs b/build.rs new file mode 100644 index 00000000..046ddc2e --- /dev/null +++ b/build.rs @@ -0,0 +1,13 @@ +use cfg_aliases::cfg_aliases; + +fn main() { + // Setup cfg aliases + cfg_aliases! { + symphonia: {any( + feature = "symphonia-mp3", + feature = "symphonia-wav", + feature = "symphonia-aac", + feature = "symphonia-isomp4" + )} + } +} diff --git a/examples/music.m4a b/examples/music.m4a new file mode 100644 index 0000000000000000000000000000000000000000..ff8135153f8b473618abed317b1134995ad6c69d GIT binary patch literal 328787 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

wLi$`AP|88VX-!4QA} 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

m!g}MX% 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

8)1QIP)dsifk8aG;HuzU`|H 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 I7#SG;FG0p)C;$Ke literal 0 HcmV?d00001 diff --git a/examples/music_m4a.rs b/examples/music_m4a.rs new file mode 100644 index 00000000..b8e494c0 --- /dev/null +++ b/examples/music_m4a.rs @@ -0,0 +1,11 @@ +use std::io::BufReader; + +fn main() { + let (_stream, handle) = rodio::OutputStream::try_default().unwrap(); + let sink = rodio::Sink::try_new(&handle).unwrap(); + + let file = std::fs::File::open("examples/music.m4a").unwrap(); + sink.append(rodio::Decoder::new(BufReader::new(file)).unwrap()); + + sink.sleep_until_end(); +} diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 54096aff..9e86a084 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -1,18 +1,34 @@ //! Decodes samples from an audio file. +#[cfg(all(feature = "symphonia-mp3", feature = "mp3"))] +compile_error!("Choose either symphonia-mp3 or mp3"); + +#[cfg(all(feature = "symphonia-wav", feature = "wav"))] +compile_error!("Choose either symphonia-wav or wav"); + use std::error::Error; use std::fmt; #[allow(unused_imports)] use std::io::{Read, Seek, SeekFrom}; use std::mem; +use std::str::FromStr; use std::time::Duration; use crate::Source; +#[cfg(symphonia)] +use self::read_seek_source::ReadSeekSource; +#[cfg(symphonia)] +use ::symphonia::core::io::{MediaSource, MediaSourceStream}; + #[cfg(feature = "flac")] mod flac; #[cfg(feature = "mp3")] mod mp3; +#[cfg(symphonia)] +mod read_seek_source; +#[cfg(symphonia)] +mod symphonia; #[cfg(feature = "vorbis")] mod vorbis; #[cfg(feature = "wav")] @@ -41,12 +57,14 @@ where Flac(flac::FlacDecoder), #[cfg(feature = "mp3")] Mp3(mp3::Mp3Decoder), + #[cfg(symphonia)] + Symphonia(symphonia::SymphoniaDecoder), None(::std::marker::PhantomData), } impl Decoder where - R: Read + Seek + Send, + R: Read + Seek + Send + 'static, { /// Builds a new decoder. /// @@ -85,6 +103,21 @@ where } }; + #[cfg(symphonia)] + { + let mss = MediaSourceStream::new( + Box::new(ReadSeekSource::new(data)) as Box, + Default::default(), + ); + + match symphonia::SymphoniaDecoder::new(mss, None) { + Err(data) => data, + Ok(decoder) => { + return Ok(Decoder(DecoderImpl::Symphonia(decoder))); + } + } + }; + Err(DecoderError::UnrecognizedFormat) } pub fn new_looped(data: R) -> Result, DecoderError> { @@ -100,6 +133,11 @@ where } } + #[cfg(feature = "symphonia-wav")] + pub fn new_wav(data: R) -> Result, DecoderError> { + Decoder::new_symphonia(data, "wav") + } + /// Builds a new decoder from flac data. #[cfg(feature = "flac")] pub fn new_flac(data: R) -> Result, DecoderError> { @@ -126,6 +164,71 @@ where Ok(decoder) => Ok(Decoder(DecoderImpl::Mp3(decoder))), } } + + #[cfg(feature = "symphonia-mp3")] + pub fn new_mp3(data: R) -> Result, DecoderError> { + Decoder::new_symphonia(data, "mp3") + } + + #[cfg(feature = "symphonia-aac")] + pub fn new_aac(data: R) -> Result, DecoderError> { + Decoder::new_symphonia(data, "aac") + } + + #[cfg(feature = "symphonia-isomp4")] + pub fn new_mp4(data: R, hint: Mp4Type) -> Result, DecoderError> { + Decoder::new_symphonia(data, &hint.to_string()) + } + + #[cfg(symphonia)] + fn new_symphonia(data: R, hint: &str) -> Result, DecoderError> { + let mss = MediaSourceStream::new( + Box::new(ReadSeekSource::new(data)) as Box, + Default::default(), + ); + + match symphonia::SymphoniaDecoder::new(mss, Some(hint)) { + Err(_) => Err(DecoderError::UnrecognizedFormat), + Ok(decoder) => { + return Ok(Decoder(DecoderImpl::Symphonia(decoder))); + } + } + } +} + +#[derive(Debug)] +pub enum Mp4Type { + Mp4, + M4a, + M4p, + M4b, + M4r, + M4v, + Mov, +} + +impl FromStr for Mp4Type { + type Err = String; + + fn from_str(input: &str) -> Result { + match &input.to_lowercase()[..] { + "mp4" => Ok(Mp4Type::Mp4), + "m4a" => Ok(Mp4Type::M4a), + "m4p" => Ok(Mp4Type::M4p), + "m4b" => Ok(Mp4Type::M4b), + "m4r" => Ok(Mp4Type::M4r), + "m4v" => Ok(Mp4Type::M4v), + "mov" => Ok(Mp4Type::Mov), + _ => Err(format!("{} is not a valid mp4 extension", input)), + } + } +} + +impl fmt::Display for Mp4Type { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let res = self.to_string().to_lowercase(); + write!(f, "{}", res) + } } impl LoopedDecoder @@ -154,6 +257,8 @@ where DecoderImpl::Flac(source) => source.next(), #[cfg(feature = "mp3")] DecoderImpl::Mp3(source) => source.next(), + #[cfg(symphonia)] + DecoderImpl::Symphonia(source) => source.next(), DecoderImpl::None(_) => None, } } @@ -169,6 +274,8 @@ where DecoderImpl::Flac(source) => source.size_hint(), #[cfg(feature = "mp3")] DecoderImpl::Mp3(source) => source.size_hint(), + #[cfg(symphonia)] + DecoderImpl::Symphonia(source) => source.size_hint(), DecoderImpl::None(_) => (0, None), } } @@ -189,6 +296,8 @@ where DecoderImpl::Flac(source) => source.current_frame_len(), #[cfg(feature = "mp3")] DecoderImpl::Mp3(source) => source.current_frame_len(), + #[cfg(symphonia)] + DecoderImpl::Symphonia(source) => source.current_frame_len(), DecoderImpl::None(_) => Some(0), } } @@ -204,6 +313,8 @@ where DecoderImpl::Flac(source) => source.channels(), #[cfg(feature = "mp3")] DecoderImpl::Mp3(source) => source.channels(), + #[cfg(symphonia)] + DecoderImpl::Symphonia(source) => source.channels(), DecoderImpl::None(_) => 0, } } @@ -219,6 +330,8 @@ where DecoderImpl::Flac(source) => source.sample_rate(), #[cfg(feature = "mp3")] DecoderImpl::Mp3(source) => source.sample_rate(), + #[cfg(symphonia)] + DecoderImpl::Symphonia(source) => source.sample_rate(), DecoderImpl::None(_) => 1, } } @@ -234,6 +347,8 @@ where DecoderImpl::Flac(source) => source.total_duration(), #[cfg(feature = "mp3")] DecoderImpl::Mp3(source) => source.total_duration(), + #[cfg(symphonia)] + DecoderImpl::Symphonia(source) => source.total_duration(), DecoderImpl::None(_) => Some(Duration::default()), } } @@ -256,6 +371,8 @@ where DecoderImpl::Flac(source) => source.next(), #[cfg(feature = "mp3")] DecoderImpl::Mp3(source) => source.next(), + #[cfg(symphonia)] + DecoderImpl::Symphonia(source) => source.next(), DecoderImpl::None(_) => None, } { Some(sample) @@ -297,6 +414,14 @@ where let sample = source.next(); (DecoderImpl::Mp3(source), sample) } + #[cfg(symphonia)] + DecoderImpl::Symphonia(source) => { + let mut reader = Box::new(source).into_inner(); + reader.seek(SeekFrom::Start(0)).ok()?; + let mut source = symphonia::SymphoniaDecoder::new(reader, None).ok()?; + let sample = source.next(); + (DecoderImpl::Symphonia(source), sample) + } none @ DecoderImpl::None(_) => (none, None), }; self.0 = decoder; @@ -315,6 +440,8 @@ where DecoderImpl::Flac(source) => (source.size_hint().0, None), #[cfg(feature = "mp3")] DecoderImpl::Mp3(source) => (source.size_hint().0, None), + #[cfg(symphonia)] + DecoderImpl::Symphonia(source) => (source.size_hint().0, None), DecoderImpl::None(_) => (0, None), } } @@ -335,6 +462,8 @@ where DecoderImpl::Flac(source) => source.current_frame_len(), #[cfg(feature = "mp3")] DecoderImpl::Mp3(source) => source.current_frame_len(), + #[cfg(symphonia)] + DecoderImpl::Symphonia(source) => source.current_frame_len(), DecoderImpl::None(_) => Some(0), } } @@ -350,6 +479,8 @@ where DecoderImpl::Flac(source) => source.channels(), #[cfg(feature = "mp3")] DecoderImpl::Mp3(source) => source.channels(), + #[cfg(symphonia)] + DecoderImpl::Symphonia(source) => source.channels(), DecoderImpl::None(_) => 0, } } @@ -365,6 +496,8 @@ where DecoderImpl::Flac(source) => source.sample_rate(), #[cfg(feature = "mp3")] DecoderImpl::Mp3(source) => source.sample_rate(), + #[cfg(symphonia)] + DecoderImpl::Symphonia(source) => source.sample_rate(), DecoderImpl::None(_) => 1, } } diff --git a/src/decoder/mp3.rs b/src/decoder/mp3.rs index 47a4cc45..973dfe19 100644 --- a/src/decoder/mp3.rs +++ b/src/decoder/mp3.rs @@ -1,4 +1,4 @@ -use std::io::{Read, Seek}; +use std::io::{Read, Seek, SeekFrom}; use std::time::Duration; use crate::Source; @@ -18,9 +18,12 @@ impl Mp3Decoder where R: Read + Seek, { - pub fn new(data: R) -> Result { + pub fn new(mut data: R) -> Result { + if !is_mp3(data.by_ref()) { + return Err(data); + } let mut decoder = Decoder::new(data); - let current_frame = decoder.next_frame().map_err(|_| ())?; + let current_frame = decoder.next_frame().unwrap(); Ok(Mp3Decoder { decoder, @@ -80,3 +83,18 @@ where Some(v) } } + +/// Returns true if the stream contains mp3 data, then resets it to where it was. +fn is_mp3(mut data: R) -> bool +where + R: Read + Seek, +{ + let stream_pos = data.seek(SeekFrom::Current(0)).unwrap(); + let mut decoder = Decoder::new(data.by_ref()); + if decoder.next_frame().is_err() { + data.seek(SeekFrom::Start(stream_pos)).unwrap(); + return false; + } + + true +} diff --git a/src/decoder/read_seek_source.rs b/src/decoder/read_seek_source.rs new file mode 100644 index 00000000..10e12dcb --- /dev/null +++ b/src/decoder/read_seek_source.rs @@ -0,0 +1,37 @@ +use std::io::{Read, Result, Seek, SeekFrom}; + +use symphonia::core::io::MediaSource; + +pub struct ReadSeekSource { + inner: T, +} + +impl ReadSeekSource { + /// Instantiates a new `ReadSeekSource` by taking ownership and wrapping the provided + /// `Read + Seek`er. + pub fn new(inner: T) -> Self { + ReadSeekSource { inner } + } +} + +impl MediaSource for ReadSeekSource { + fn is_seekable(&self) -> bool { + true + } + + fn len(&self) -> Option { + None + } +} + +impl Read for ReadSeekSource { + fn read(&mut self, buf: &mut [u8]) -> Result { + self.inner.read(buf) + } +} + +impl Seek for ReadSeekSource { + fn seek(&mut self, pos: SeekFrom) -> Result { + self.inner.seek(pos) + } +} diff --git a/src/decoder/symphonia.rs b/src/decoder/symphonia.rs new file mode 100644 index 00000000..e460b9ff --- /dev/null +++ b/src/decoder/symphonia.rs @@ -0,0 +1,131 @@ +use std::time::Duration; + +use symphonia::core::{ + audio::SampleBuffer, + codecs::{Decoder, DecoderOptions}, + formats::{FormatOptions, FormatReader, Packet}, + io::MediaSourceStream, + meta::MetadataOptions, + probe::Hint, + units, +}; + +use crate::Source; + +pub struct SymphoniaDecoder { + decoder: Box, + current_frame: Packet, + current_frame_offset: usize, + format: Box, + buffer: SampleBuffer, + channels: usize, +} + +unsafe impl Send for SymphoniaDecoder {} + +impl SymphoniaDecoder { + pub fn new(mss: MediaSourceStream, extension: Option<&str>) -> Result { + let mut hint = Hint::new(); + if let Some(ext) = extension { + hint.with_extension(ext); + } + let format_opts: FormatOptions = Default::default(); + let metadata_opts: MetadataOptions = Default::default(); + let mut probed = symphonia::default::get_probe() + .format(&hint, mss, &format_opts, &metadata_opts) + .unwrap(); + + let stream = probed.format.default_stream().unwrap(); + + let mut decoder = symphonia::default::get_codecs() + .make( + &stream.codec_params, + &DecoderOptions { + verify: true, + ..Default::default() + }, + ) + .unwrap(); + + let current_frame = probed.format.next_packet().unwrap(); + + let decoded = decoder.decode(¤t_frame).unwrap(); + let spec = decoded.spec().clone(); + let duration = symphonia::core::units::Duration::from(decoded.capacity() as u64); + let mut buf = SampleBuffer::::new(duration, spec.to_owned()); + buf.copy_interleaved_ref(decoded); + + return Ok(SymphoniaDecoder { + decoder, + current_frame, + current_frame_offset: 0, + format: probed.format, + buffer: buf, + channels: spec.channels.count(), + }); + } + pub fn into_inner(self: Box) -> MediaSourceStream { + self.format.into_inner() + } +} + +impl Source for SymphoniaDecoder { + #[inline] + fn current_frame_len(&self) -> Option { + Some(self.buffer.samples().len()) + } + + #[inline] + fn channels(&self) -> u16 { + self.channels as u16 + } + + #[inline] + fn sample_rate(&self) -> u32 { + self.format + .default_stream() + .unwrap() + .codec_params + .sample_rate + .unwrap() + } + + #[inline] + fn total_duration(&self) -> Option { + None + } +} + +impl Iterator for SymphoniaDecoder { + type Item = i16; + + #[inline] + fn next(&mut self) -> Option { + if self.current_frame_offset == self.buffer.len() { + match self.format.next_packet() { + Ok(packet) => { + self.current_frame = packet; + + match self.decoder.decode(&self.current_frame) { + Ok(decoded) => { + let spec = decoded.spec(); + let duration = units::Duration::from(decoded.capacity() as u64); + let mut buf = SampleBuffer::::new(duration, spec.to_owned()); + buf.copy_interleaved_ref(decoded); + self.buffer = buf; + } + Err(_) => return None, + } + } + Err(_) => return None, + } + self.current_frame_offset = 0; + } + + let sample = self.buffer.samples()[self.current_frame_offset]; + + self.current_frame_offset += 1; + + Some(sample) + } +} From c70d5a38d21b7edb430166f76e0c6e71795441a4 Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Thu, 10 Jun 2021 12:16:01 -0500 Subject: [PATCH 02/18] add symphonia-flac --- Cargo.toml | 7 ++++--- build.rs | 3 ++- src/decoder/mod.rs | 10 ++++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f8f0aa37..9eb3343e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,15 +15,16 @@ cpal = "0.13" hound = {version = "3.3.1", optional = true} lewton = {version = "0.10", optional = true} minimp3 = {version = "0.5.0", optional = true} -symphonia = {path = "../symphonia/symphonia", optional = true, default-features = false} +symphonia = {git = "https://github.com/pdeljanov/Symphonia", rev = "4331015", optional = true, default-features = false} [features] -default = ["flac", "vorbis", "symphonia-all"] +default = ["vorbis", "symphonia-all"] flac = ["claxon"] mp3 = ["minimp3"] symphonia-aac = ["symphonia/aac"] -symphonia-all = ["symphonia-aac", "symphonia-isomp4", "symphonia-mp3", "symphonia-wav"] +symphonia-all = ["symphonia-aac", "symphonia-flac", "symphonia-isomp4", "symphonia-mp3", "symphonia-wav"] +symphonia-flac = ["symphonia/flac"] symphonia-isomp4 = ["symphonia/isomp4"] symphonia-mp3 = ["symphonia/mp3"] symphonia-wav = ["symphonia/wav", "symphonia/pcm"] diff --git a/build.rs b/build.rs index 046ddc2e..2e57a9a0 100644 --- a/build.rs +++ b/build.rs @@ -7,7 +7,8 @@ fn main() { feature = "symphonia-mp3", feature = "symphonia-wav", feature = "symphonia-aac", - feature = "symphonia-isomp4" + feature = "symphonia-isomp4", + feature = "symphonia-flac" )} } } diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 9e86a084..6c5cc6f0 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -133,6 +133,7 @@ where } } + /// Builds a new decoder from wav data. #[cfg(feature = "symphonia-wav")] pub fn new_wav(data: R) -> Result, DecoderError> { Decoder::new_symphonia(data, "wav") @@ -147,6 +148,12 @@ where } } + /// Builds a new decoder from flac data. + #[cfg(feature = "symphonia-flac")] + pub fn new_flac(data: R) -> Result, DecoderError> { + Decoder::new_symphonia(data, "flac") + } + /// Builds a new decoder from vorbis data. #[cfg(feature = "vorbis")] pub fn new_vorbis(data: R) -> Result, DecoderError> { @@ -165,16 +172,19 @@ where } } + /// Builds a new decoder from mp3 data. #[cfg(feature = "symphonia-mp3")] pub fn new_mp3(data: R) -> Result, DecoderError> { Decoder::new_symphonia(data, "mp3") } + /// Builds a new decoder from aac data. #[cfg(feature = "symphonia-aac")] pub fn new_aac(data: R) -> Result, DecoderError> { Decoder::new_symphonia(data, "aac") } + /// Builds a new decoder from mp4 data. #[cfg(feature = "symphonia-isomp4")] pub fn new_mp4(data: R, hint: Mp4Type) -> Result, DecoderError> { Decoder::new_symphonia(data, &hint.to_string()) From 4f6d543211e3904257e3f83e5ecf26cd71970808 Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Thu, 10 Jun 2021 23:16:06 -0500 Subject: [PATCH 03/18] better compile errors --- Cargo.toml | 2 +- build.rs | 16 +++++++++------- src/decoder/mod.rs | 10 ++++++++-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9eb3343e..e0e2f613 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ minimp3 = {version = "0.5.0", optional = true} symphonia = {git = "https://github.com/pdeljanov/Symphonia", rev = "4331015", optional = true, default-features = false} [features] -default = ["vorbis", "symphonia-all"] +default = ["vorbis", "mp3", "flac", "wav"] flac = ["claxon"] mp3 = ["minimp3"] diff --git a/build.rs b/build.rs index 2e57a9a0..8de548c4 100644 --- a/build.rs +++ b/build.rs @@ -3,12 +3,14 @@ use cfg_aliases::cfg_aliases; fn main() { // Setup cfg aliases cfg_aliases! { - symphonia: {any( - feature = "symphonia-mp3", - feature = "symphonia-wav", - feature = "symphonia-aac", - feature = "symphonia-isomp4", - feature = "symphonia-flac" - )} + symphonia: { + any( + feature = "symphonia-mp3", + feature = "symphonia-wav", + feature = "symphonia-aac", + feature = "symphonia-isomp4", + feature = "symphonia-flac" + ) + } } } diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 6c5cc6f0..5cd5ae96 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -1,10 +1,16 @@ //! Decodes samples from an audio file. #[cfg(all(feature = "symphonia-mp3", feature = "mp3"))] -compile_error!("Choose either symphonia-mp3 or mp3"); +compile_error!("Both symphonia-mp3 and mp3 are enabled. +If you enabled symphonia-mp3 or symphonia-all, make sure to set default-features=false to disable the default mp3 decoder"); #[cfg(all(feature = "symphonia-wav", feature = "wav"))] -compile_error!("Choose either symphonia-wav or wav"); +compile_error!("Both symphonia-wav and wav are enabled. +If you enabled symphonia-wav or symphonia-all, make sure to set default-features=false to disable the default wav decoder"); + +#[cfg(all(feature = "symphonia-flac", feature = "flac"))] +compile_error!("Both symphonia-flac and flac are enabled. +If you enabled symphonia-flac or symphonia-all, make sure to set default-features=false to disable the default flac decoder"); use std::error::Error; use std::fmt; From 7c31cd399559947f92bb391a7e34896620541965 Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Thu, 10 Jun 2021 23:26:42 -0500 Subject: [PATCH 04/18] remove unsafe send --- src/decoder/symphonia.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/decoder/symphonia.rs b/src/decoder/symphonia.rs index e460b9ff..25d01c8c 100644 --- a/src/decoder/symphonia.rs +++ b/src/decoder/symphonia.rs @@ -21,8 +21,6 @@ pub struct SymphoniaDecoder { channels: usize, } -unsafe impl Send for SymphoniaDecoder {} - impl SymphoniaDecoder { pub fn new(mss: MediaSourceStream, extension: Option<&str>) -> Result { let mut hint = Hint::new(); From 8dfdac0d16dfbde29eba24b1d4d4d75a4d5e44ed Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Sun, 13 Jun 2021 11:22:20 -0500 Subject: [PATCH 05/18] update ci --- .github/workflows/ci.yml | 9 +++++---- Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 63b9037e..bc5228a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ on: branches: [main, master] env: - RUSTFLAGS: "-C debuginfo=0 -D warnings" + RUSTFLAGS: '-C debuginfo=0 -D warnings' CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 @@ -30,8 +30,8 @@ jobs: - name: install linux deps run: | - sudo apt update - sudo apt install --no-install-recommends libasound2-dev pkg-config + apt-get update + apt-get install -y --no-install-recommends libasound2-dev pkg-config if: contains(matrix.os, 'ubuntu') - name: install ${{ matrix.toolchain }} toolchain @@ -55,7 +55,8 @@ jobs: cargo fmt --all -- --check if: matrix.toolchain == 'stable' && matrix.os == 'ubuntu-latest' - - run: cargo test --all-targets --all-features + - run: cargo test --all-targets + - run: cargo test --no-default-features --features=symphonia-all --all-targets cargo-publish: if: github.event_name == 'push' && github.ref == 'refs/heads/master' env: diff --git a/Cargo.toml b/Cargo.toml index e0e2f613..2db0eb52 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ cpal = "0.13" hound = {version = "3.3.1", optional = true} lewton = {version = "0.10", optional = true} minimp3 = {version = "0.5.0", optional = true} -symphonia = {git = "https://github.com/pdeljanov/Symphonia", rev = "4331015", optional = true, default-features = false} +symphonia = {git = "https://github.com/pdeljanov/Symphonia", rev = "1587c01", optional = true, default-features = false} [features] default = ["vorbis", "mp3", "flac", "wav"] From 7c953cec31048277d2fe13bee338edf296c10114 Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Sun, 13 Jun 2021 11:28:28 -0500 Subject: [PATCH 06/18] sudo --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc5228a9..21b53bf1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,8 +30,8 @@ jobs: - name: install linux deps run: | - apt-get update - apt-get install -y --no-install-recommends libasound2-dev pkg-config + sudo apt-get update + sudo apt-get install -y --no-install-recommends libasound2-dev pkg-config if: contains(matrix.os, 'ubuntu') - name: install ${{ matrix.toolchain }} toolchain From f246b9b632deb6e0cbf8dcc7596c3f1f59ee60ab Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Sun, 13 Jun 2021 11:49:30 -0500 Subject: [PATCH 07/18] disable duration check because symphonia does not support it --- tests/flac_test.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/flac_test.rs b/tests/flac_test.rs index 729ac31e..1ff4a083 100644 --- a/tests/flac_test.rs +++ b/tests/flac_test.rs @@ -1,12 +1,18 @@ +#[cfg(feature = "flac")] use rodio::Source; -use std::{io::BufReader, time::Duration}; +use std::io::BufReader; +#[cfg(feature = "flac")] +use std::time::Duration; #[test] fn test_flac_encodings() { // 16 bit FLAC file exported from Audacity (2 channels, compression level 5) let file = std::fs::File::open("tests/audacity16bit_level5.flac").unwrap(); let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap(); - assert!(decoder.any(|x| x != 0)); // File is not just silence + // File is not just silence + assert!(decoder.any(|x| x != 0)); + // Symphonia does not expose functionality to get the duration so this check must be disabled + #[cfg(feature = "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) @@ -14,6 +20,7 @@ fn test_flac_encodings() { let file = std::fs::File::open(format!("tests/audacity24bit_level{}.flac", level)).unwrap(); let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap(); assert!(decoder.any(|x| x != 0)); + #[cfg(feature = "flac")] assert_eq!(decoder.total_duration(), Some(Duration::from_secs(3))); } } From 41ae680bc79afd3baa6b1a382c164460fc0bee44 Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Sun, 13 Jun 2021 14:04:29 -0500 Subject: [PATCH 08/18] add error handling --- .github/workflows/ci.yml | 6 +-- Cargo.toml | 1 + src/decoder/mod.rs | 49 ++++++++++++---------- src/decoder/symphonia.rs | 88 ++++++++++++++++++++++++++-------------- 4 files changed, 90 insertions(+), 54 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 21b53bf1..b043399c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,8 +30,8 @@ jobs: - name: install linux deps run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends libasound2-dev pkg-config + sudo apt update + sudo apt install -y --no-install-recommends libasound2-dev pkg-config if: contains(matrix.os, 'ubuntu') - name: install ${{ matrix.toolchain }} toolchain @@ -67,7 +67,7 @@ jobs: - name: Update apt run: sudo apt update - name: Install alsa - run: sudo apt install --no-install-recommends libasound2-dev pkg-config + run: sudo apt install -y --no-install-recommends libasound2-dev pkg-config - name: Run cargo publish for rodio continue-on-error: true run: | diff --git a/Cargo.toml b/Cargo.toml index 2db0eb52..c4bc35b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ hound = {version = "3.3.1", optional = true} lewton = {version = "0.10", optional = true} minimp3 = {version = "0.5.0", optional = true} symphonia = {git = "https://github.com/pdeljanov/Symphonia", rev = "1587c01", optional = true, default-features = false} +thiserror = "1.0.25" [features] default = ["vorbis", "mp3", "flac", "wav"] diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 5cd5ae96..0686d60f 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -12,13 +12,13 @@ If you enabled symphonia-wav or symphonia-all, make sure to set default-features compile_error!("Both symphonia-flac and flac are enabled. If you enabled symphonia-flac or symphonia-all, make sure to set default-features=false to disable the default flac decoder"); -use std::error::Error; use std::fmt; #[allow(unused_imports)] use std::io::{Read, Seek, SeekFrom}; use std::mem; use std::str::FromStr; use std::time::Duration; +use thiserror::Error; use crate::Source; @@ -116,14 +116,14 @@ where Default::default(), ); - match symphonia::SymphoniaDecoder::new(mss, None) { - Err(data) => data, + return match symphonia::SymphoniaDecoder::new(mss, None) { + Err(e) => Err(e), Ok(decoder) => { return Ok(Decoder(DecoderImpl::Symphonia(decoder))); } - } + }; }; - + #[cfg(not(symphonia))] Err(DecoderError::UnrecognizedFormat) } pub fn new_looped(data: R) -> Result, DecoderError> { @@ -204,7 +204,7 @@ where ); match symphonia::SymphoniaDecoder::new(mss, Some(hint)) { - Err(_) => Err(DecoderError::UnrecognizedFormat), + Err(e) => Err(e), Ok(decoder) => { return Ok(Decoder(DecoderImpl::Symphonia(decoder))); } @@ -525,24 +525,31 @@ where } /// Error that can happen when creating a decoder. -#[derive(Debug, Clone)] +#[derive(Debug, Error)] pub enum DecoderError { /// The format of the data has not been recognized. + #[error("Unrecognized format")] UnrecognizedFormat, -} -impl fmt::Display for DecoderError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - DecoderError::UnrecognizedFormat => write!(f, "Unrecognized format"), - } - } -} + /// The underlying Symphonia decoder returned an error + #[error(transparent)] + #[cfg(symphonia)] + IoError(#[from] std::io::Error), -impl Error for DecoderError { - fn description(&self) -> &str { - match self { - DecoderError::UnrecognizedFormat => "Unrecognized format", - } - } + #[error("Decode Error: {0}")] + #[cfg(symphonia)] + DecoderError(&'static str), + + #[error("Limit Error: {0}")] + #[cfg(symphonia)] + LimitError(&'static str), + + #[cfg(symphonia)] + #[error("The demuxer or decoder needs to be reset before continuing")] + ResetRequired, + + /// No streams were found by the decoder + #[error("No streams found")] + #[cfg(symphonia)] + NoStreams, } diff --git a/src/decoder/symphonia.rs b/src/decoder/symphonia.rs index 25d01c8c..b6f93f73 100644 --- a/src/decoder/symphonia.rs +++ b/src/decoder/symphonia.rs @@ -1,17 +1,21 @@ use std::time::Duration; - -use symphonia::core::{ - audio::SampleBuffer, - codecs::{Decoder, DecoderOptions}, - formats::{FormatOptions, FormatReader, Packet}, - io::MediaSourceStream, - meta::MetadataOptions, - probe::Hint, - units, +use symphonia::{ + core::{ + audio::SampleBuffer, + codecs::{Decoder, DecoderOptions}, + formats::{FormatOptions, FormatReader, Packet}, + io::MediaSourceStream, + meta::MetadataOptions, + probe::Hint, + units, + }, + default::get_probe, }; use crate::Source; +use super::DecoderError; + pub struct SymphoniaDecoder { decoder: Box, current_frame: Packet, @@ -22,48 +26,72 @@ pub struct SymphoniaDecoder { } impl SymphoniaDecoder { - pub fn new(mss: MediaSourceStream, extension: Option<&str>) -> Result { + pub fn new(mss: MediaSourceStream, extension: Option<&str>) -> Result { + match SymphoniaDecoder::init(mss, extension) { + Err(e) => match e { + symphonia::core::errors::Error::IoError(e) => Err(DecoderError::IoError(e)), + symphonia::core::errors::Error::DecodeError(e) => { + Err(DecoderError::DecoderError(e)) + } + symphonia::core::errors::Error::SeekError(_) => { + unreachable!("Seek errors should not occur during initialization") + } + symphonia::core::errors::Error::Unsupported(_) => { + Err(DecoderError::UnrecognizedFormat) + } + symphonia::core::errors::Error::LimitError(e) => Err(DecoderError::LimitError(e)), + symphonia::core::errors::Error::ResetRequired => Err(DecoderError::ResetRequired), + }, + Ok(Some(decoder)) => Ok(decoder), + Ok(None) => Err(DecoderError::NoStreams), + } + } + + pub fn into_inner(self: Box) -> MediaSourceStream { + self.format.into_inner() + } + + fn init( + mss: MediaSourceStream, + extension: Option<&str>, + ) -> symphonia::core::errors::Result> { let mut hint = Hint::new(); if let Some(ext) = extension { hint.with_extension(ext); } let format_opts: FormatOptions = Default::default(); let metadata_opts: MetadataOptions = Default::default(); - let mut probed = symphonia::default::get_probe() - .format(&hint, mss, &format_opts, &metadata_opts) - .unwrap(); + let mut probed = get_probe().format(&hint, mss, &format_opts, &metadata_opts)?; - let stream = probed.format.default_stream().unwrap(); + let stream = match probed.format.default_stream() { + Some(stream) => stream, + None => return Ok(None), + }; - let mut decoder = symphonia::default::get_codecs() - .make( - &stream.codec_params, - &DecoderOptions { - verify: true, - ..Default::default() - }, - ) - .unwrap(); + let mut decoder = symphonia::default::get_codecs().make( + &stream.codec_params, + &DecoderOptions { + verify: true, + ..Default::default() + }, + )?; - let current_frame = probed.format.next_packet().unwrap(); + let current_frame = probed.format.next_packet()?; - let decoded = decoder.decode(¤t_frame).unwrap(); + let decoded = decoder.decode(¤t_frame)?; let spec = decoded.spec().clone(); let duration = symphonia::core::units::Duration::from(decoded.capacity() as u64); let mut buf = SampleBuffer::::new(duration, spec.to_owned()); buf.copy_interleaved_ref(decoded); - return Ok(SymphoniaDecoder { + return Ok(Some(SymphoniaDecoder { decoder, current_frame, current_frame_offset: 0, format: probed.format, buffer: buf, channels: spec.channels.count(), - }); - } - pub fn into_inner(self: Box) -> MediaSourceStream { - self.format.into_inner() + })); } } From 5190f66580a1e079a80a2486a20667ebb9cec238 Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Sun, 13 Jun 2021 14:24:35 -0500 Subject: [PATCH 09/18] cleanup --- Cargo.toml | 2 +- build.rs | 3 ++- src/decoder/mod.rs | 16 ++++++++++------ src/decoder/symphonia.rs | 5 +---- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c4bc35b5..1ffc4502 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ symphonia = {git = "https://github.com/pdeljanov/Symphonia", rev = "1587c01", op thiserror = "1.0.25" [features] -default = ["vorbis", "mp3", "flac", "wav"] +default = ["flac", "mp3", "vorbis", "wav"] flac = ["claxon"] mp3 = ["minimp3"] diff --git a/build.rs b/build.rs index 8de548c4..a3668953 100644 --- a/build.rs +++ b/build.rs @@ -1,7 +1,8 @@ use cfg_aliases::cfg_aliases; fn main() { - // Setup cfg aliases + // Add alias to see if any symphonia features are enabled + // This prevents having to copy/paste this large cfg check each time cfg_aliases! { symphonia: { any( diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 0686d60f..b6cbb534 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -116,13 +116,13 @@ where Default::default(), ); - return match symphonia::SymphoniaDecoder::new(mss, None) { + match symphonia::SymphoniaDecoder::new(mss, None) { Err(e) => Err(e), Ok(decoder) => { return Ok(Decoder(DecoderImpl::Symphonia(decoder))); } - }; - }; + } + } #[cfg(not(symphonia))] Err(DecoderError::UnrecognizedFormat) } @@ -531,21 +531,25 @@ pub enum DecoderError { #[error("Unrecognized format")] UnrecognizedFormat, - /// The underlying Symphonia decoder returned an error + /// An IO error occured while reading, writing, or seeking the stream. #[error(transparent)] #[cfg(symphonia)] IoError(#[from] std::io::Error), + /// The stream contained malformed data and could not be decoded or demuxed. #[error("Decode Error: {0}")] #[cfg(symphonia)] - DecoderError(&'static str), + DecodeError(&'static str), + /// A default or user-defined limit was reached while decoding or demuxing the stream. Limits + /// are used to prevent denial-of-service attacks from malicious streams. #[error("Limit Error: {0}")] #[cfg(symphonia)] LimitError(&'static str), - #[cfg(symphonia)] + /// The demuxer or decoder needs to be reset before continuing. #[error("The demuxer or decoder needs to be reset before continuing")] + #[cfg(symphonia)] ResetRequired, /// No streams were found by the decoder diff --git a/src/decoder/symphonia.rs b/src/decoder/symphonia.rs index b6f93f73..ac946d02 100644 --- a/src/decoder/symphonia.rs +++ b/src/decoder/symphonia.rs @@ -30,9 +30,7 @@ impl SymphoniaDecoder { match SymphoniaDecoder::init(mss, extension) { Err(e) => match e { symphonia::core::errors::Error::IoError(e) => Err(DecoderError::IoError(e)), - symphonia::core::errors::Error::DecodeError(e) => { - Err(DecoderError::DecoderError(e)) - } + symphonia::core::errors::Error::DecodeError(e) => Err(DecoderError::DecodeError(e)), symphonia::core::errors::Error::SeekError(_) => { unreachable!("Seek errors should not occur during initialization") } @@ -149,7 +147,6 @@ impl Iterator for SymphoniaDecoder { } let sample = self.buffer.samples()[self.current_frame_offset]; - self.current_frame_offset += 1; Some(sample) From 19becf546d9c252737289f4b9e9cab45585290cf Mon Sep 17 00:00:00 2001 From: aschey Date: Fri, 25 Jun 2021 23:09:43 -0500 Subject: [PATCH 10/18] update symphonia and fix breaking changes --- Cargo.toml | 2 +- src/decoder/symphonia.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1ffc4502..64db9e9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ cpal = "0.13" hound = {version = "3.3.1", optional = true} lewton = {version = "0.10", optional = true} minimp3 = {version = "0.5.0", optional = true} -symphonia = {git = "https://github.com/pdeljanov/Symphonia", rev = "1587c01", optional = true, default-features = false} +symphonia = {git = "https://github.com/pdeljanov/Symphonia", rev = "38fe3fa", optional = true, default-features = false} thiserror = "1.0.25" [features] diff --git a/src/decoder/symphonia.rs b/src/decoder/symphonia.rs index ac946d02..239f33ef 100644 --- a/src/decoder/symphonia.rs +++ b/src/decoder/symphonia.rs @@ -61,7 +61,7 @@ impl SymphoniaDecoder { let metadata_opts: MetadataOptions = Default::default(); let mut probed = get_probe().format(&hint, mss, &format_opts, &metadata_opts)?; - let stream = match probed.format.default_stream() { + let stream = match probed.format.default_track() { Some(stream) => stream, None => return Ok(None), }; @@ -107,7 +107,7 @@ impl Source for SymphoniaDecoder { #[inline] fn sample_rate(&self) -> u32 { self.format - .default_stream() + .default_track() .unwrap() .codec_params .sample_rate From 17d1c7e5e0b1ba5fa05be6b7e765d6a311ff5b49 Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Sat, 26 Jun 2021 22:05:10 -0500 Subject: [PATCH 11/18] update to published symphonia version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 64db9e9d..bd672210 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ cpal = "0.13" hound = {version = "3.3.1", optional = true} lewton = {version = "0.10", optional = true} minimp3 = {version = "0.5.0", optional = true} -symphonia = {git = "https://github.com/pdeljanov/Symphonia", rev = "38fe3fa", optional = true, default-features = false} +symphonia = {version = "0.3", optional = true, default-features = false} thiserror = "1.0.25" [features] From 3ee6369b6a11bc4d4cc67d5633369a630e4387e4 Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Sat, 26 Jun 2021 22:57:09 -0500 Subject: [PATCH 12/18] update docs --- README.md | 20 ++++++++++++-------- src/lib.rs | 12 ++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index eb5967fe..9947a07d 100644 --- a/README.md +++ b/README.md @@ -6,23 +6,27 @@ Rust playback library. - - Playback is handled by [cpal](https://github.com/RustAudio/cpal). - - MP3 decoding is handled by [minimp3](https://github.com/lieff/minimp3). - - WAV decoding is handled by [hound](https://github.com/ruud-v-a/hound). - - Vorbis decoding is handled by [lewton](https://github.com/est31/lewton). - - Flac decoding is handled by [claxon](https://github.com/ruuda/claxon). +- Playback is handled by [CPAL](https://github.com/RustAudio/cpal). +- MP3 decoding is handled by [Minimp3](https://github.com/lieff/minimp3). +- WAV decoding is handled by [Hound](https://github.com/ruud-v-a/hound). +- Vorbis decoding is handled by [Lewton](https://github.com/est31/lewton). +- FLAC decoding is handled by [Claxon](https://github.com/ruuda/claxon). +- MP4 and AAC (both disabled by default) are handled by [Symphonia](https://github.com/pdeljanov/Symphonia) + +Alternatively, Symphonia can be used to decode any of the other codecs above with the exception of Vorbis. See the docs for more details on backends. # [Documentation](http://docs.rs/rodio) [The documentation](http://docs.rs/rodio) contains an introduction to the library. ## License -[License]: #license + +[license]: #license Licensed under either of -* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0), or -* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0), or +- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. diff --git a/src/lib.rs b/src/lib.rs index 07919471..e321b7e4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -84,6 +84,18 @@ //! let source = source.take_duration(Duration::from_secs(5)).repeat_infinite(); //! ``` //! +//! ## Alternative Decoder Backends +//! +//! [Symphonia](https://github.com/pdeljanov/Symphonia) is an alternative deocder library that can be used in place of many of the default backends. +//! Currently, the main benefit is that Symphonia is the only decoder library that supports M4A and AAC, +//! but it may be used to implement additional optional functionality in the future. +//! +//! To enable, set `default-features = false` and enable either the `symphonia-all` feature to enable all Symphonia codecs +//! or enable specific codecs using one of the `symphonia-{codec name}` features. +//! See the [available feature flags](https://docs.rs/crate/rodio/latest/features) for all options. +//! Note that Symphonia does not currently support Vorbis, so the `vorbis` feature should be explicitly used to re-enable the default vorbis decoder +//! if default features are disabled. +//! //! ## How it works under the hood //! //! Rodio spawns a background thread that is dedicated to reading from the sources and sending From 94eea1c666725b2a50dc508d18de78748101d395 Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Sat, 26 Jun 2021 23:58:51 -0500 Subject: [PATCH 13/18] reduce namespace duplication --- src/decoder/symphonia.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/decoder/symphonia.rs b/src/decoder/symphonia.rs index 239f33ef..f7890def 100644 --- a/src/decoder/symphonia.rs +++ b/src/decoder/symphonia.rs @@ -3,6 +3,7 @@ use symphonia::{ core::{ audio::SampleBuffer, codecs::{Decoder, DecoderOptions}, + errors::Error, formats::{FormatOptions, FormatReader, Packet}, io::MediaSourceStream, meta::MetadataOptions, @@ -29,16 +30,14 @@ impl SymphoniaDecoder { pub fn new(mss: MediaSourceStream, extension: Option<&str>) -> Result { match SymphoniaDecoder::init(mss, extension) { Err(e) => match e { - symphonia::core::errors::Error::IoError(e) => Err(DecoderError::IoError(e)), - symphonia::core::errors::Error::DecodeError(e) => Err(DecoderError::DecodeError(e)), - symphonia::core::errors::Error::SeekError(_) => { + Error::IoError(e) => Err(DecoderError::IoError(e)), + Error::DecodeError(e) => Err(DecoderError::DecodeError(e)), + Error::SeekError(_) => { unreachable!("Seek errors should not occur during initialization") } - symphonia::core::errors::Error::Unsupported(_) => { - Err(DecoderError::UnrecognizedFormat) - } - symphonia::core::errors::Error::LimitError(e) => Err(DecoderError::LimitError(e)), - symphonia::core::errors::Error::ResetRequired => Err(DecoderError::ResetRequired), + Error::Unsupported(_) => Err(DecoderError::UnrecognizedFormat), + Error::LimitError(e) => Err(DecoderError::LimitError(e)), + Error::ResetRequired => Err(DecoderError::ResetRequired), }, Ok(Some(decoder)) => Ok(decoder), Ok(None) => Err(DecoderError::NoStreams), @@ -78,7 +77,7 @@ impl SymphoniaDecoder { let decoded = decoder.decode(¤t_frame)?; let spec = decoded.spec().clone(); - let duration = symphonia::core::units::Duration::from(decoded.capacity() as u64); + let duration = units::Duration::from(decoded.capacity() as u64); let mut buf = SampleBuffer::::new(duration, spec.to_owned()); buf.copy_interleaved_ref(decoded); From 3743ef31e3d75e6526a810b1e0ee9995eef67bdd Mon Sep 17 00:00:00 2001 From: aschey Date: Sun, 27 Jun 2021 18:43:47 -0500 Subject: [PATCH 14/18] remove extra reference to current frame --- src/decoder/symphonia.rs | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/decoder/symphonia.rs b/src/decoder/symphonia.rs index f7890def..9545105e 100644 --- a/src/decoder/symphonia.rs +++ b/src/decoder/symphonia.rs @@ -4,7 +4,7 @@ use symphonia::{ audio::SampleBuffer, codecs::{Decoder, DecoderOptions}, errors::Error, - formats::{FormatOptions, FormatReader, Packet}, + formats::{FormatOptions, FormatReader}, io::MediaSourceStream, meta::MetadataOptions, probe::Hint, @@ -19,7 +19,6 @@ use super::DecoderError; pub struct SymphoniaDecoder { decoder: Box, - current_frame: Packet, current_frame_offset: usize, format: Box, buffer: SampleBuffer, @@ -83,7 +82,6 @@ impl SymphoniaDecoder { return Ok(Some(SymphoniaDecoder { decoder, - current_frame, current_frame_offset: 0, format: probed.format, buffer: buf, @@ -126,20 +124,16 @@ impl Iterator for SymphoniaDecoder { fn next(&mut self) -> Option { if self.current_frame_offset == self.buffer.len() { match self.format.next_packet() { - Ok(packet) => { - self.current_frame = packet; - - match self.decoder.decode(&self.current_frame) { - Ok(decoded) => { - let spec = decoded.spec(); - let duration = units::Duration::from(decoded.capacity() as u64); - let mut buf = SampleBuffer::::new(duration, spec.to_owned()); - buf.copy_interleaved_ref(decoded); - self.buffer = buf; - } - Err(_) => return None, + Ok(packet) => match self.decoder.decode(&packet) { + Ok(decoded) => { + let spec = decoded.spec(); + let duration = units::Duration::from(decoded.capacity() as u64); + let mut buf = SampleBuffer::::new(duration, spec.to_owned()); + buf.copy_interleaved_ref(decoded); + self.buffer = buf; } - } + Err(_) => return None, + }, Err(_) => return None, } self.current_frame_offset = 0; From b0ce8f32535ac2ff4b86dae20e2e3037b98b2320 Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Mon, 28 Jun 2021 22:15:11 -0500 Subject: [PATCH 15/18] pr comments --- .github/workflows/ci.yml | 4 +- Cargo.toml | 34 ++++--- README.md | 23 +++-- build.rs | 17 ---- src/decoder/mod.rs | 188 ++++++++++++++++++++------------------- src/decoder/symphonia.rs | 2 +- src/lib.rs | 4 +- 7 files changed, 127 insertions(+), 145 deletions(-) delete mode 100644 build.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b043399c..a433c847 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ on: branches: [main, master] env: - RUSTFLAGS: '-C debuginfo=0 -D warnings' + RUSTFLAGS: "-C debuginfo=0 -D warnings" CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 @@ -56,7 +56,7 @@ jobs: if: matrix.toolchain == 'stable' && matrix.os == 'ubuntu-latest' - run: cargo test --all-targets - - run: cargo test --no-default-features --features=symphonia-all --all-targets + - run: cargo test --features=symphonia-all --all-targets cargo-publish: if: github.event_name == 'push' && github.ref == 'refs/heads/master' env: diff --git a/Cargo.toml b/Cargo.toml index bd672210..2880d572 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,44 +1,40 @@ [package] +name = "rodio" +version = "0.14.0" authors = ["Pierre Krieger "] +license = "MIT OR Apache-2.0" description = "Audio playback library" -documentation = "http://docs.rs/rodio" -edition = "2018" keywords = ["audio", "playback", "gamedev"] -license = "MIT OR Apache-2.0" -name = "rodio" repository = "https://github.com/RustAudio/rodio" -version = "0.14.0" +documentation = "http://docs.rs/rodio" +edition = "2018" [dependencies] -claxon = {version = "0.4.2", optional = true} cpal = "0.13" -hound = {version = "3.3.1", optional = true} -lewton = {version = "0.10", optional = true} -minimp3 = {version = "0.5.0", optional = true} -symphonia = {version = "0.3", optional = true, default-features = false} -thiserror = "1.0.25" +claxon = { version = "0.4.2", optional = true } +hound = { version = "3.3.1", optional = true } +lewton = { version = "0.10", optional = true } +minimp3 = { version = "0.5.0", optional = true } +symphonia = {version = "0.3", optional = true } [features] -default = ["flac", "mp3", "vorbis", "wav"] +default = ["flac", "vorbis", "wav", "mp3"] flac = ["claxon"] +vorbis = ["lewton"] +wav = ["hound"] mp3 = ["minimp3"] +wasm-bindgen = ["cpal/wasm-bindgen"] symphonia-aac = ["symphonia/aac"] symphonia-all = ["symphonia-aac", "symphonia-flac", "symphonia-isomp4", "symphonia-mp3", "symphonia-wav"] symphonia-flac = ["symphonia/flac"] symphonia-isomp4 = ["symphonia/isomp4"] symphonia-mp3 = ["symphonia/mp3"] symphonia-wav = ["symphonia/wav", "symphonia/pcm"] -vorbis = ["lewton"] -wasm-bindgen = ["cpal/wasm-bindgen"] -wav = ["hound"] [dev-dependencies] quickcheck = "0.9.2" -[build-dependencies] -cfg_aliases = "0.1.1" - [[example]] name = "music_m4a" -required-features = ["symphonia-isomp4", "symphonia-aac"] +required-features = ["symphonia-isomp4", "symphonia-aac"] \ No newline at end of file diff --git a/README.md b/README.md index 9947a07d..e3d28965 100644 --- a/README.md +++ b/README.md @@ -6,30 +6,29 @@ Rust playback library. -- Playback is handled by [CPAL](https://github.com/RustAudio/cpal). -- MP3 decoding is handled by [Minimp3](https://github.com/lieff/minimp3). -- WAV decoding is handled by [Hound](https://github.com/ruud-v-a/hound). -- Vorbis decoding is handled by [Lewton](https://github.com/est31/lewton). -- FLAC decoding is handled by [Claxon](https://github.com/ruuda/claxon). -- MP4 and AAC (both disabled by default) are handled by [Symphonia](https://github.com/pdeljanov/Symphonia) + - Playback is handled by [cpal](https://github.com/RustAudio/cpal). + - MP3 decoding is handled by [minimp3](https://github.com/lieff/minimp3). + - WAV decoding is handled by [hound](https://github.com/ruud-v-a/hound). + - Vorbis decoding is handled by [lewton](https://github.com/est31/lewton). + - Flac decoding is handled by [claxon](https://github.com/ruuda/claxon). + - MP4 and AAC (both disabled by default) are handled by [Symphonia](https://github.com/pdeljanov/Symphonia). -Alternatively, Symphonia can be used to decode any of the other codecs above with the exception of Vorbis. See the docs for more details on backends. + Alternatively, Symphonia can be used to decode any of the other codecs above with the exception of Vorbis. See the docs for more details on backends. # [Documentation](http://docs.rs/rodio) [The documentation](http://docs.rs/rodio) contains an introduction to the library. ## License - -[license]: #license +[License]: #license Licensed under either of -- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0), or -- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) +* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0), or +* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. ### License of your contributions -Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. \ No newline at end of file diff --git a/build.rs b/build.rs deleted file mode 100644 index a3668953..00000000 --- a/build.rs +++ /dev/null @@ -1,17 +0,0 @@ -use cfg_aliases::cfg_aliases; - -fn main() { - // Add alias to see if any symphonia features are enabled - // This prevents having to copy/paste this large cfg check each time - cfg_aliases! { - symphonia: { - any( - feature = "symphonia-mp3", - feature = "symphonia-wav", - feature = "symphonia-aac", - feature = "symphonia-isomp4", - feature = "symphonia-flac" - ) - } - } -} diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 51ece685..3cb9a810 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -1,39 +1,27 @@ //! Decodes samples from an audio file. -#[cfg(all(feature = "symphonia-mp3", feature = "mp3"))] -compile_error!("Both symphonia-mp3 and mp3 are enabled. -If you enabled symphonia-mp3 or symphonia-all, make sure to set default-features=false to disable the default mp3 decoder"); - -#[cfg(all(feature = "symphonia-wav", feature = "wav"))] -compile_error!("Both symphonia-wav and wav are enabled. -If you enabled symphonia-wav or symphonia-all, make sure to set default-features=false to disable the default wav decoder"); - -#[cfg(all(feature = "symphonia-flac", feature = "flac"))] -compile_error!("Both symphonia-flac and flac are enabled. -If you enabled symphonia-flac or symphonia-all, make sure to set default-features=false to disable the default flac decoder"); - +use std::error::Error; use std::fmt; #[allow(unused_imports)] use std::io::{Read, Seek, SeekFrom}; use std::mem; use std::str::FromStr; use std::time::Duration; -use thiserror::Error; use crate::Source; -#[cfg(symphonia)] +#[cfg(feature = "symphonia")] use self::read_seek_source::ReadSeekSource; -#[cfg(symphonia)] +#[cfg(feature = "symphonia")] use ::symphonia::core::io::{MediaSource, MediaSourceStream}; #[cfg(feature = "flac")] mod flac; #[cfg(feature = "mp3")] mod mp3; -#[cfg(symphonia)] +#[cfg(feature = "symphonia")] mod read_seek_source; -#[cfg(symphonia)] +#[cfg(feature = "symphonia")] mod symphonia; #[cfg(feature = "vorbis")] mod vorbis; @@ -55,15 +43,15 @@ enum DecoderImpl where R: Read + Seek, { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] Wav(wav::WavDecoder), #[cfg(feature = "vorbis")] Vorbis(vorbis::VorbisDecoder), - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] Flac(flac::FlacDecoder), - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] Mp3(mp3::Mp3Decoder), - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] Symphonia(symphonia::SymphoniaDecoder), None(::std::marker::PhantomData), } @@ -77,7 +65,7 @@ where /// Attempts to automatically detect the format of the source of data. #[allow(unused_variables)] pub fn new(data: R) -> Result, DecoderError> { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] let data = match wav::WavDecoder::new(data) { Err(data) => data, Ok(decoder) => { @@ -85,7 +73,7 @@ where } }; - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] let data = match flac::FlacDecoder::new(data) { Err(data) => data, Ok(decoder) => { @@ -101,7 +89,7 @@ where } }; - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] let data = match mp3::Mp3Decoder::new(data) { Err(data) => data, Ok(decoder) => { @@ -109,7 +97,7 @@ where } }; - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] { let mss = MediaSourceStream::new( Box::new(ReadSeekSource::new(data)) as Box, @@ -123,7 +111,7 @@ where } } } - #[cfg(not(symphonia))] + #[cfg(not(feature = "symphonia"))] Err(DecoderError::UnrecognizedFormat) } pub fn new_looped(data: R) -> Result, DecoderError> { @@ -131,7 +119,7 @@ where } /// Builds a new decoder from wav data. - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] pub fn new_wav(data: R) -> Result, DecoderError> { match wav::WavDecoder::new(data) { Err(_) => Err(DecoderError::UnrecognizedFormat), @@ -146,7 +134,7 @@ where } /// Builds a new decoder from flac data. - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] pub fn new_flac(data: R) -> Result, DecoderError> { match flac::FlacDecoder::new(data) { Err(_) => Err(DecoderError::UnrecognizedFormat), @@ -170,7 +158,7 @@ where } /// Builds a new decoder from mp3 data. - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] pub fn new_mp3(data: R) -> Result, DecoderError> { match mp3::Mp3Decoder::new(data) { Err(_) => Err(DecoderError::UnrecognizedFormat), @@ -196,7 +184,7 @@ where Decoder::new_symphonia(data, &hint.to_string()) } - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] fn new_symphonia(data: R, hint: &str) -> Result, DecoderError> { let mss = MediaSourceStream::new( Box::new(ReadSeekSource::new(data)) as Box, @@ -265,15 +253,15 @@ where #[inline] fn next(&mut self) -> Option { match &mut self.0 { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] DecoderImpl::Wav(source) => source.next(), #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(source) => source.next(), - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] DecoderImpl::Flac(source) => source.next(), - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] DecoderImpl::Mp3(source) => source.next(), - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source) => source.next(), DecoderImpl::None(_) => None, } @@ -282,15 +270,15 @@ where #[inline] fn size_hint(&self) -> (usize, Option) { match &self.0 { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] DecoderImpl::Wav(source) => source.size_hint(), #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(source) => source.size_hint(), - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] DecoderImpl::Flac(source) => source.size_hint(), - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] DecoderImpl::Mp3(source) => source.size_hint(), - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source) => source.size_hint(), DecoderImpl::None(_) => (0, None), } @@ -304,15 +292,15 @@ where #[inline] fn current_frame_len(&self) -> Option { match &self.0 { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] DecoderImpl::Wav(source) => source.current_frame_len(), #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(source) => source.current_frame_len(), - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] DecoderImpl::Flac(source) => source.current_frame_len(), - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] DecoderImpl::Mp3(source) => source.current_frame_len(), - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source) => source.current_frame_len(), DecoderImpl::None(_) => Some(0), } @@ -321,15 +309,15 @@ where #[inline] fn channels(&self) -> u16 { match &self.0 { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] DecoderImpl::Wav(source) => source.channels(), #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(source) => source.channels(), - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] DecoderImpl::Flac(source) => source.channels(), - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] DecoderImpl::Mp3(source) => source.channels(), - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source) => source.channels(), DecoderImpl::None(_) => 0, } @@ -338,15 +326,15 @@ where #[inline] fn sample_rate(&self) -> u32 { match &self.0 { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] DecoderImpl::Wav(source) => source.sample_rate(), #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(source) => source.sample_rate(), - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] DecoderImpl::Flac(source) => source.sample_rate(), - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] DecoderImpl::Mp3(source) => source.sample_rate(), - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source) => source.sample_rate(), DecoderImpl::None(_) => 1, } @@ -355,15 +343,15 @@ where #[inline] fn total_duration(&self) -> Option { match &self.0 { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] DecoderImpl::Wav(source) => source.total_duration(), #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(source) => source.total_duration(), - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] DecoderImpl::Flac(source) => source.total_duration(), - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] DecoderImpl::Mp3(source) => source.total_duration(), - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source) => source.total_duration(), DecoderImpl::None(_) => Some(Duration::default()), } @@ -379,15 +367,15 @@ where #[inline] fn next(&mut self) -> Option { if let Some(sample) = match &mut self.0 { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] DecoderImpl::Wav(source) => source.next(), #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(source) => source.next(), - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] DecoderImpl::Flac(source) => source.next(), - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] DecoderImpl::Mp3(source) => source.next(), - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source) => source.next(), DecoderImpl::None(_) => None, } { @@ -395,7 +383,7 @@ where } else { let decoder = mem::replace(&mut self.0, DecoderImpl::None(Default::default())); let (decoder, sample) = match decoder { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] DecoderImpl::Wav(source) => { let mut reader = source.into_inner(); reader.seek(SeekFrom::Start(0)).ok()?; @@ -414,7 +402,7 @@ where let sample = source.next(); (DecoderImpl::Vorbis(source), sample) } - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] DecoderImpl::Flac(source) => { let mut reader = source.into_inner(); reader.seek(SeekFrom::Start(0)).ok()?; @@ -422,7 +410,7 @@ where let sample = source.next(); (DecoderImpl::Flac(source), sample) } - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] DecoderImpl::Mp3(source) => { let mut reader = source.into_inner(); reader.seek(SeekFrom::Start(0)).ok()?; @@ -430,7 +418,7 @@ where let sample = source.next(); (DecoderImpl::Mp3(source), sample) } - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source) => { let mut reader = Box::new(source).into_inner(); reader.seek(SeekFrom::Start(0)).ok()?; @@ -448,15 +436,15 @@ where #[inline] fn size_hint(&self) -> (usize, Option) { match &self.0 { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] DecoderImpl::Wav(source) => (source.size_hint().0, None), #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(source) => (source.size_hint().0, None), - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] DecoderImpl::Flac(source) => (source.size_hint().0, None), - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] DecoderImpl::Mp3(source) => (source.size_hint().0, None), - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source) => (source.size_hint().0, None), DecoderImpl::None(_) => (0, None), } @@ -470,15 +458,15 @@ where #[inline] fn current_frame_len(&self) -> Option { match &self.0 { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] DecoderImpl::Wav(source) => source.current_frame_len(), #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(source) => source.current_frame_len(), - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] DecoderImpl::Flac(source) => source.current_frame_len(), - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] DecoderImpl::Mp3(source) => source.current_frame_len(), - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source) => source.current_frame_len(), DecoderImpl::None(_) => Some(0), } @@ -487,15 +475,15 @@ where #[inline] fn channels(&self) -> u16 { match &self.0 { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] DecoderImpl::Wav(source) => source.channels(), #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(source) => source.channels(), - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] DecoderImpl::Flac(source) => source.channels(), - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] DecoderImpl::Mp3(source) => source.channels(), - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source) => source.channels(), DecoderImpl::None(_) => 0, } @@ -504,15 +492,15 @@ where #[inline] fn sample_rate(&self) -> u32 { match &self.0 { - #[cfg(feature = "wav")] + #[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] DecoderImpl::Wav(source) => source.sample_rate(), #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(source) => source.sample_rate(), - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] DecoderImpl::Flac(source) => source.sample_rate(), - #[cfg(feature = "mp3")] + #[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] DecoderImpl::Mp3(source) => source.sample_rate(), - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source) => source.sample_rate(), DecoderImpl::None(_) => 1, } @@ -525,35 +513,53 @@ where } /// Error that can happen when creating a decoder. -#[derive(Debug, Error)] +#[derive(Debug, Clone)] pub enum DecoderError { /// The format of the data has not been recognized. - #[error("Unrecognized format")] UnrecognizedFormat, /// An IO error occured while reading, writing, or seeking the stream. - #[error(transparent)] - #[cfg(symphonia)] - IoError(#[from] std::io::Error), + #[cfg(feature = "symphonia")] + IoError(String), /// The stream contained malformed data and could not be decoded or demuxed. - #[error("Decode Error: {0}")] - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] DecodeError(&'static str), /// A default or user-defined limit was reached while decoding or demuxing the stream. Limits /// are used to prevent denial-of-service attacks from malicious streams. - #[error("Limit Error: {0}")] - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] LimitError(&'static str), /// The demuxer or decoder needs to be reset before continuing. - #[error("The demuxer or decoder needs to be reset before continuing")] - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] ResetRequired, /// No streams were found by the decoder - #[error("No streams found")] - #[cfg(symphonia)] + #[cfg(feature = "symphonia")] NoStreams, } + +impl fmt::Display for DecoderError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.to_string()) + } +} + +impl Error for DecoderError { + fn description(&self) -> &str { + match self { + DecoderError::UnrecognizedFormat => "Unrecognized format", + #[cfg(feature = "symphonia")] + DecoderError::IoError(msg) => &msg[..], + #[cfg(feature = "symphonia")] + DecoderError::DecodeError(msg) => msg, + #[cfg(feature = "symphonia")] + DecoderError::LimitError(msg) => msg, + #[cfg(feature = "symphonia")] + DecoderError::ResetRequired => "Reset required", + #[cfg(feature = "symphonia")] + DecoderError::NoStreams => "No streams", + } + } +} diff --git a/src/decoder/symphonia.rs b/src/decoder/symphonia.rs index f7890def..295335bf 100644 --- a/src/decoder/symphonia.rs +++ b/src/decoder/symphonia.rs @@ -30,7 +30,7 @@ impl SymphoniaDecoder { pub fn new(mss: MediaSourceStream, extension: Option<&str>) -> Result { match SymphoniaDecoder::init(mss, extension) { Err(e) => match e { - Error::IoError(e) => Err(DecoderError::IoError(e)), + Error::IoError(e) => Err(DecoderError::IoError(e.to_string())), Error::DecodeError(e) => Err(DecoderError::DecodeError(e)), Error::SeekError(_) => { unreachable!("Seek errors should not occur during initialization") diff --git a/src/lib.rs b/src/lib.rs index e321b7e4..636afc84 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,11 +90,9 @@ //! Currently, the main benefit is that Symphonia is the only decoder library that supports M4A and AAC, //! but it may be used to implement additional optional functionality in the future. //! -//! To enable, set `default-features = false` and enable either the `symphonia-all` feature to enable all Symphonia codecs +//! 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. //! See the [available feature flags](https://docs.rs/crate/rodio/latest/features) for all options. -//! Note that Symphonia does not currently support Vorbis, so the `vorbis` feature should be explicitly used to re-enable the default vorbis decoder -//! if default features are disabled. //! //! ## How it works under the hood //! From c99f9799db155c2a1525708c6133f2ed71bdf82f Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Mon, 28 Jun 2021 22:23:11 -0500 Subject: [PATCH 16/18] exclude decoders from module if unused --- src/decoder/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 3cb9a810..88b539d4 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -15,9 +15,9 @@ use self::read_seek_source::ReadSeekSource; #[cfg(feature = "symphonia")] use ::symphonia::core::io::{MediaSource, MediaSourceStream}; -#[cfg(feature = "flac")] +#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] mod flac; -#[cfg(feature = "mp3")] +#[cfg(all(feature = "mp3", not(feature = "symphonia-mp3")))] mod mp3; #[cfg(feature = "symphonia")] mod read_seek_source; @@ -25,7 +25,7 @@ mod read_seek_source; mod symphonia; #[cfg(feature = "vorbis")] mod vorbis; -#[cfg(feature = "wav")] +#[cfg(all(feature = "wav", not(feature = "symphonia-wav")))] mod wav; /// Source of audio samples from decoding a file. From c3efb1c6b9ecc9aef73a9bab457dd8f3cd4d2896 Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Mon, 28 Jun 2021 22:27:21 -0500 Subject: [PATCH 17/18] fix flac test --- tests/flac_test.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/flac_test.rs b/tests/flac_test.rs index 1ff4a083..769310e8 100644 --- a/tests/flac_test.rs +++ b/tests/flac_test.rs @@ -1,7 +1,7 @@ -#[cfg(feature = "flac")] +#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] use rodio::Source; use std::io::BufReader; -#[cfg(feature = "flac")] +#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] use std::time::Duration; #[test] @@ -12,7 +12,7 @@ fn test_flac_encodings() { // File is not just silence assert!(decoder.any(|x| x != 0)); // Symphonia does not expose functionality to get the duration so this check must be disabled - #[cfg(feature = "flac")] + #[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) @@ -20,7 +20,7 @@ fn test_flac_encodings() { let file = std::fs::File::open(format!("tests/audacity24bit_level{}.flac", level)).unwrap(); let mut decoder = rodio::Decoder::new(BufReader::new(file)).unwrap(); assert!(decoder.any(|x| x != 0)); - #[cfg(feature = "flac")] + #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] assert_eq!(decoder.total_duration(), Some(Duration::from_secs(3))); } } From 2825d2bb085a130b9201349592e04fdd55008098 Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Mon, 28 Jun 2021 22:38:25 -0500 Subject: [PATCH 18/18] recommend disabling default features with symphonia --- src/lib.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 636afc84..13a871bf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,12 +86,15 @@ //! //! ## Alternative Decoder Backends //! -//! [Symphonia](https://github.com/pdeljanov/Symphonia) is an alternative deocder library that can be used in place of many of the default backends. -//! Currently, the main benefit is that Symphonia is the only decoder library that supports M4A and AAC, +//! [Symphonia](https://github.com/pdeljanov/Symphonia) is an alternative deocder 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. //! //! ## How it works under the hood