From 3ef6b0564fe93e2345b1018c43891d9a6d02a387 Mon Sep 17 00:00:00 2001 From: "Andriy S. from cobalt" Date: Sun, 29 Oct 2017 17:57:21 +0200 Subject: [PATCH 1/3] make wav/flac/vorbis decoding features optional --- Cargo.toml | 13 ++++++++++--- src/decoder/mod.rs | 47 ++++++++++++++++++++++++++++++++++++++-------- src/lib.rs | 7 +++++++ 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8bce285..a8804ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,10 +9,17 @@ repository = "https://github.com/tomaka/rodio" documentation = "http://docs.rs/rodio" [dependencies] -claxon = "0.3.0" +claxon = { version = "0.3.0", optional = true } cpal = "0.4.0" futures = "0.1.1" -hound = "1.0.0" +hound = { version = "1.0.0", optional = true } lazy_static = "0.1.12" -lewton = "0.5" +lewton = { version = "0.5", optional = true } cgmath = "0.14" + +[features] +default = ["flac", "vorbis", "wav"] + +flac = ["claxon"] +vorbis = ["lewton"] +wav = ["hound"] diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 24bbf64..22bb0d4 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -7,8 +7,11 @@ use std::time::Duration; use Source; +#[cfg(feature = "flac")] mod flac; +#[cfg(feature = "vorbis")] mod vorbis; +#[cfg(feature = "wav")] mod wav; /// Source of audio samples from decoding a file. @@ -19,8 +22,11 @@ pub struct Decoder(DecoderImpl) where R: Read + Seek; enum DecoderImpl where R: Read + Seek { + #[cfg(feature = "wav")] Wav(wav::WavDecoder), + #[cfg(feature = "vorbis")] Vorbis(vorbis::VorbisDecoder), + #[cfg(feature = "flac")] Flac(flac::FlacDecoder), } @@ -30,29 +36,36 @@ impl Decoder /// Builds a new decoder. /// /// Attempts to automatically detect the format of the source of data. - pub fn new(data: R) -> Result, DecoderError> { - let data = match wav::WavDecoder::new(data) { - Err(data) => data, + pub fn new(_data: R) -> Result, DecoderError> { + #[cfg(feature = "wav")] + let _data = match wav::WavDecoder::new(_data) { + Err(_data) => _data, Ok(decoder) => { return Ok(Decoder(DecoderImpl::Wav(decoder))); }, }; - let data = match flac::FlacDecoder::new(data) { - Err(data) => data, + #[cfg(feature = "flac")] + let _data = match flac::FlacDecoder::new(_data) { + Err(_data) => _data, Ok(decoder) => { return Ok(Decoder(DecoderImpl::Flac(decoder))); }, }; - if let Ok(decoder) = vorbis::VorbisDecoder::new(data) { - return Ok(Decoder(DecoderImpl::Vorbis(decoder))); - } + #[cfg(feature = "vorbis")] + let _data = match vorbis::VorbisDecoder::new(_data) { + Err(_data) => _data, + Ok(decoder) => { + return Ok(Decoder(DecoderImpl::Vorbis(decoder))); + }, + }; Err(DecoderError::UnrecognizedFormat) } } + impl Iterator for Decoder where R: Read + Seek { @@ -61,8 +74,11 @@ impl Iterator for Decoder #[inline] fn next(&mut self) -> Option { match self.0 { + #[cfg(feature = "wav")] DecoderImpl::Wav(ref mut source) => source.next(), + #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(ref mut source) => source.next(), + #[cfg(feature = "flac")] DecoderImpl::Flac(ref mut source) => source.next(), } } @@ -70,8 +86,11 @@ impl Iterator for Decoder #[inline] fn size_hint(&self) -> (usize, Option) { match self.0 { + #[cfg(feature = "wav")] DecoderImpl::Wav(ref source) => source.size_hint(), + #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(ref source) => source.size_hint(), + #[cfg(feature = "flac")] DecoderImpl::Flac(ref source) => source.size_hint(), } } @@ -83,8 +102,11 @@ impl Source for Decoder #[inline] fn current_frame_len(&self) -> Option { match self.0 { + #[cfg(feature = "wav")] DecoderImpl::Wav(ref source) => source.current_frame_len(), + #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(ref source) => source.current_frame_len(), + #[cfg(feature = "flac")] DecoderImpl::Flac(ref source) => source.current_frame_len(), } } @@ -92,8 +114,11 @@ impl Source for Decoder #[inline] fn channels(&self) -> u16 { match self.0 { + #[cfg(feature = "wav")] DecoderImpl::Wav(ref source) => source.channels(), + #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(ref source) => source.channels(), + #[cfg(feature = "flac")] DecoderImpl::Flac(ref source) => source.channels(), } } @@ -101,8 +126,11 @@ impl Source for Decoder #[inline] fn samples_rate(&self) -> u32 { match self.0 { + #[cfg(feature = "wav")] DecoderImpl::Wav(ref source) => source.samples_rate(), + #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(ref source) => source.samples_rate(), + #[cfg(feature = "flac")] DecoderImpl::Flac(ref source) => source.samples_rate(), } } @@ -110,8 +138,11 @@ impl Source for Decoder #[inline] fn total_duration(&self) -> Option { match self.0 { + #[cfg(feature = "wav")] DecoderImpl::Wav(ref source) => source.total_duration(), + #[cfg(feature = "vorbis")] DecoderImpl::Vorbis(ref source) => source.total_duration(), + #[cfg(feature = "flac")] DecoderImpl::Flac(ref source) => source.total_duration(), } } diff --git a/src/lib.rs b/src/lib.rs index ae19d96..f4c04fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,24 +83,29 @@ #![cfg_attr(test, deny(missing_docs))] +#[cfg(feature = "flac")] extern crate claxon; extern crate cpal; extern crate futures; +#[cfg(feature = "wav")] extern crate hound; #[macro_use] extern crate lazy_static; +#[cfg(feature = "vorbis")] extern crate lewton; extern crate cgmath; pub use cpal::{Endpoint, get_default_endpoint, get_endpoints_list}; pub use conversions::Sample; +#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))] pub use decoder::Decoder; pub use engine::play_raw; pub use sink::Sink; pub use source::Source; pub use spatial_sink::SpatialSink; +#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))] use std::io::{Read, Seek}; mod conversions; @@ -109,6 +114,7 @@ mod sink; mod spatial_sink; pub mod buffer; +#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))] pub mod decoder; pub mod dynamic_mixer; pub mod queue; @@ -116,6 +122,7 @@ pub mod source; /// Plays a sound once. Returns a `Sink` that can be used to control the sound. #[inline] +#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))] pub fn play_once(endpoint: &Endpoint, input: R) -> Result where R: Read + Seek + Send + 'static { From bfad440f6a67f98350dce594479da13ff7700eea Mon Sep 17 00:00:00 2001 From: "Andriy S. from cobalt" Date: Sun, 29 Oct 2017 20:39:02 +0200 Subject: [PATCH 2/3] use allow attr instead of _ vars --- src/decoder/mod.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 22bb0d4..3720e23 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -36,26 +36,27 @@ impl Decoder /// Builds a new decoder. /// /// Attempts to automatically detect the format of the source of data. - pub fn new(_data: R) -> Result, DecoderError> { + #[allow(unused_variables)] + pub fn new(data: R) -> Result, DecoderError> { #[cfg(feature = "wav")] - let _data = match wav::WavDecoder::new(_data) { - Err(_data) => _data, + let data = match wav::WavDecoder::new(data) { + Err(data) => data, Ok(decoder) => { return Ok(Decoder(DecoderImpl::Wav(decoder))); }, }; #[cfg(feature = "flac")] - let _data = match flac::FlacDecoder::new(_data) { - Err(_data) => _data, + let data = match flac::FlacDecoder::new(data) { + Err(data) => data, Ok(decoder) => { return Ok(Decoder(DecoderImpl::Flac(decoder))); }, }; #[cfg(feature = "vorbis")] - let _data = match vorbis::VorbisDecoder::new(_data) { - Err(_data) => _data, + let data = match vorbis::VorbisDecoder::new(data) { + Err(data) => data, Ok(decoder) => { return Ok(Decoder(DecoderImpl::Vorbis(decoder))); }, From b14006ec99413f3a4f48a06607493554607c2259 Mon Sep 17 00:00:00 2001 From: "Andriy S. from cobalt" Date: Sun, 29 Oct 2017 21:18:01 +0200 Subject: [PATCH 3/3] have play_once fn and Decoder trait even if decoders are turned off --- src/decoder/mod.rs | 25 +++++++++++++++++++++++++ src/lib.rs | 4 ---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 3720e23..608471b 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -17,8 +17,13 @@ mod wav; /// Source of audio samples from decoding a file. /// /// Supports WAV, Vorbis and Flac. +#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))] pub struct Decoder(DecoderImpl) where R: Read + Seek; +#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis")))] +pub struct Decoder(::std::marker::PhantomData); + +#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))] enum DecoderImpl where R: Read + Seek { @@ -66,7 +71,16 @@ impl Decoder } } +#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis")))] +impl Iterator for Decoder + where R: Read + Seek +{ + type Item = i16; + fn next(&mut self) -> Option { None } +} + +#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))] impl Iterator for Decoder where R: Read + Seek { @@ -97,6 +111,17 @@ impl Iterator for Decoder } } +#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis")))] +impl Source for Decoder + where R: Read + Seek +{ + fn current_frame_len(&self) -> Option { Some(0) } + fn channels(&self) -> u16 { 0 } + fn samples_rate(&self) -> u32 { 1 } + fn total_duration(&self) -> Option { Some(Duration::default()) } +} + +#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))] impl Source for Decoder where R: Read + Seek { diff --git a/src/lib.rs b/src/lib.rs index 3837e29..a557ebf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -97,14 +97,12 @@ extern crate cgmath; pub use cpal::{Endpoint, default_endpoint, endpoints, get_default_endpoint, get_endpoints_list}; pub use conversions::Sample; -#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))] pub use decoder::Decoder; pub use engine::play_raw; pub use sink::Sink; pub use source::Source; pub use spatial_sink::SpatialSink; -#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))] use std::io::{Read, Seek}; mod conversions; @@ -113,7 +111,6 @@ mod sink; mod spatial_sink; pub mod buffer; -#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))] pub mod decoder; pub mod dynamic_mixer; pub mod queue; @@ -121,7 +118,6 @@ pub mod source; /// Plays a sound once. Returns a `Sink` that can be used to control the sound. #[inline] -#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))] pub fn play_once(endpoint: &Endpoint, input: R) -> Result where R: Read + Seek + Send + 'static {