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"
[dependencies]
claxon = "0.3.0"
claxon = { version = "0.3.0", optional = true }
cpal = "0.5.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"]

View file

@ -7,20 +7,31 @@ 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.
///
/// Supports WAV, Vorbis and Flac.
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
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>
where R: Read + Seek
{
#[cfg(feature = "wav")]
Wav(wav::WavDecoder<R>),
#[cfg(feature = "vorbis")]
Vorbis(vorbis::VorbisDecoder<R>),
#[cfg(feature = "flac")]
Flac(flac::FlacDecoder<R>),
}
@ -30,7 +41,9 @@ impl<R> Decoder<R>
/// Builds a new decoder.
///
/// Attempts to automatically detect the format of the source of data.
#[allow(unused_variables)]
pub fn new(data: R) -> Result<Decoder<R>, DecoderError> {
#[cfg(feature = "wav")]
let data = match wav::WavDecoder::new(data) {
Err(data) => data,
Ok(decoder) => {
@ -38,6 +51,7 @@ impl<R> Decoder<R>
},
};
#[cfg(feature = "flac")]
let data = match flac::FlacDecoder::new(data) {
Err(data) => data,
Ok(decoder) => {
@ -45,14 +59,28 @@ impl<R> Decoder<R>
},
};
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)
}
}
#[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>
where R: Read + Seek
{
@ -61,8 +89,11 @@ impl<R> Iterator for Decoder<R>
#[inline]
fn next(&mut self) -> Option<i16> {
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,21 +101,38 @@ impl<R> Iterator for Decoder<R>
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
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(),
}
}
}
#[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>
where R: Read + Seek
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
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 +140,11 @@ impl<R> Source for Decoder<R>
#[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 +152,11 @@ impl<R> Source for Decoder<R>
#[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 +164,11 @@ impl<R> Source for Decoder<R>
#[inline]
fn total_duration(&self) -> Option<Duration> {
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(),
}
}

View file

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