Merge pull request #146 from chyvonomys/optional-decoders

Optional decoders
This commit is contained in:
tomaka 2017-10-30 07:26:46 +01:00 committed by GitHub
commit a9d2ab1ac5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 6 deletions

View file

@ -9,9 +9,16 @@ repository = "https://github.com/tomaka/rodio"
documentation = "http://docs.rs/rodio" documentation = "http://docs.rs/rodio"
[dependencies] [dependencies]
claxon = "0.3.0" claxon = { version = "0.3.0", optional = true }
cpal = "0.5.1" cpal = "0.5.1"
hound = "1.0.0" hound = { version = "1.0.0", optional = true }
lazy_static = "0.1.12" lazy_static = "0.1.12"
lewton = "0.5" lewton = { version = "0.5", optional = true }
cgmath = "0.14" cgmath = "0.14"
[features]
default = ["flac", "vorbis", "wav"]
flac = ["claxon"]
vorbis = ["lewton"]
wav = ["hound"]

View file

@ -7,20 +7,31 @@ use std::time::Duration;
use Source; use Source;
#[cfg(feature = "flac")]
mod flac; mod flac;
#[cfg(feature = "vorbis")]
mod vorbis; mod vorbis;
#[cfg(feature = "wav")]
mod wav; mod wav;
/// Source of audio samples from decoding a file. /// Source of audio samples from decoding a file.
/// ///
/// Supports WAV, Vorbis and Flac. /// Supports WAV, Vorbis and Flac.
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
pub struct Decoder<R>(DecoderImpl<R>) where R: Read + Seek; pub struct Decoder<R>(DecoderImpl<R>) where R: Read + Seek;
#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis")))]
pub struct Decoder<R>(::std::marker::PhantomData<R>);
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
enum DecoderImpl<R> enum DecoderImpl<R>
where R: Read + Seek where R: Read + Seek
{ {
#[cfg(feature = "wav")]
Wav(wav::WavDecoder<R>), Wav(wav::WavDecoder<R>),
#[cfg(feature = "vorbis")]
Vorbis(vorbis::VorbisDecoder<R>), Vorbis(vorbis::VorbisDecoder<R>),
#[cfg(feature = "flac")]
Flac(flac::FlacDecoder<R>), Flac(flac::FlacDecoder<R>),
} }
@ -30,7 +41,9 @@ impl<R> Decoder<R>
/// Builds a new decoder. /// Builds a new decoder.
/// ///
/// Attempts to automatically detect the format of the source of data. /// Attempts to automatically detect the format of the source of data.
#[allow(unused_variables)]
pub fn new(data: R) -> Result<Decoder<R>, DecoderError> { pub fn new(data: R) -> Result<Decoder<R>, DecoderError> {
#[cfg(feature = "wav")]
let data = match wav::WavDecoder::new(data) { let data = match wav::WavDecoder::new(data) {
Err(data) => data, Err(data) => data,
Ok(decoder) => { Ok(decoder) => {
@ -38,6 +51,7 @@ impl<R> Decoder<R>
}, },
}; };
#[cfg(feature = "flac")]
let data = match flac::FlacDecoder::new(data) { let data = match flac::FlacDecoder::new(data) {
Err(data) => data, Err(data) => data,
Ok(decoder) => { Ok(decoder) => {
@ -45,14 +59,28 @@ impl<R> Decoder<R>
}, },
}; };
if let Ok(decoder) = vorbis::VorbisDecoder::new(data) { #[cfg(feature = "vorbis")]
return Ok(Decoder(DecoderImpl::Vorbis(decoder))); let data = match vorbis::VorbisDecoder::new(data) {
} Err(data) => data,
Ok(decoder) => {
return Ok(Decoder(DecoderImpl::Vorbis(decoder)));
},
};
Err(DecoderError::UnrecognizedFormat) Err(DecoderError::UnrecognizedFormat)
} }
} }
#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis")))]
impl<R> Iterator for Decoder<R>
where R: Read + Seek
{
type Item = i16;
fn next(&mut self) -> Option<i16> { None }
}
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
impl<R> Iterator for Decoder<R> impl<R> Iterator for Decoder<R>
where R: Read + Seek where R: Read + Seek
{ {
@ -61,8 +89,11 @@ impl<R> Iterator for Decoder<R>
#[inline] #[inline]
fn next(&mut self) -> Option<i16> { fn next(&mut self) -> Option<i16> {
match self.0 { match self.0 {
#[cfg(feature = "wav")]
DecoderImpl::Wav(ref mut source) => source.next(), DecoderImpl::Wav(ref mut source) => source.next(),
#[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref mut source) => source.next(), DecoderImpl::Vorbis(ref mut source) => source.next(),
#[cfg(feature = "flac")]
DecoderImpl::Flac(ref mut source) => source.next(), DecoderImpl::Flac(ref mut source) => source.next(),
} }
} }
@ -70,21 +101,38 @@ impl<R> Iterator for Decoder<R>
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
match self.0 { match self.0 {
#[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.size_hint(), DecoderImpl::Wav(ref source) => source.size_hint(),
#[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.size_hint(), DecoderImpl::Vorbis(ref source) => source.size_hint(),
#[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.size_hint(), DecoderImpl::Flac(ref source) => source.size_hint(),
} }
} }
} }
#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis")))]
impl<R> Source for Decoder<R>
where R: Read + Seek
{
fn current_frame_len(&self) -> Option<usize> { Some(0) }
fn channels(&self) -> u16 { 0 }
fn samples_rate(&self) -> u32 { 1 }
fn total_duration(&self) -> Option<Duration> { Some(Duration::default()) }
}
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
impl<R> Source for Decoder<R> impl<R> Source for Decoder<R>
where R: Read + Seek where R: Read + Seek
{ {
#[inline] #[inline]
fn current_frame_len(&self) -> Option<usize> { fn current_frame_len(&self) -> Option<usize> {
match self.0 { match self.0 {
#[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.current_frame_len(), DecoderImpl::Wav(ref source) => source.current_frame_len(),
#[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.current_frame_len(), DecoderImpl::Vorbis(ref source) => source.current_frame_len(),
#[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.current_frame_len(), DecoderImpl::Flac(ref source) => source.current_frame_len(),
} }
} }
@ -92,8 +140,11 @@ impl<R> Source for Decoder<R>
#[inline] #[inline]
fn channels(&self) -> u16 { fn channels(&self) -> u16 {
match self.0 { match self.0 {
#[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.channels(), DecoderImpl::Wav(ref source) => source.channels(),
#[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.channels(), DecoderImpl::Vorbis(ref source) => source.channels(),
#[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.channels(), DecoderImpl::Flac(ref source) => source.channels(),
} }
} }
@ -101,8 +152,11 @@ impl<R> Source for Decoder<R>
#[inline] #[inline]
fn samples_rate(&self) -> u32 { fn samples_rate(&self) -> u32 {
match self.0 { match self.0 {
#[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.samples_rate(), DecoderImpl::Wav(ref source) => source.samples_rate(),
#[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.samples_rate(), DecoderImpl::Vorbis(ref source) => source.samples_rate(),
#[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.samples_rate(), DecoderImpl::Flac(ref source) => source.samples_rate(),
} }
} }
@ -110,8 +164,11 @@ impl<R> Source for Decoder<R>
#[inline] #[inline]
fn total_duration(&self) -> Option<Duration> { fn total_duration(&self) -> Option<Duration> {
match self.0 { match self.0 {
#[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.total_duration(), DecoderImpl::Wav(ref source) => source.total_duration(),
#[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.total_duration(), DecoderImpl::Vorbis(ref source) => source.total_duration(),
#[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.total_duration(), DecoderImpl::Flac(ref source) => source.total_duration(),
} }
} }

View file

@ -83,11 +83,14 @@
#![cfg_attr(test, deny(missing_docs))] #![cfg_attr(test, deny(missing_docs))]
#[cfg(feature = "flac")]
extern crate claxon; extern crate claxon;
extern crate cpal; extern crate cpal;
#[cfg(feature = "wav")]
extern crate hound; extern crate hound;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
#[cfg(feature = "vorbis")]
extern crate lewton; extern crate lewton;
extern crate cgmath; extern crate cgmath;