mirror of
https://github.com/RustAudio/rodio
synced 2024-11-10 14:14:21 +00:00
parent
c5725b8a37
commit
5c54078126
2 changed files with 110 additions and 7 deletions
|
@ -9,6 +9,8 @@ use Source;
|
|||
|
||||
#[cfg(feature = "flac")]
|
||||
mod flac;
|
||||
#[cfg(feature = "mp3")]
|
||||
mod mp3;
|
||||
#[cfg(feature = "vorbis")]
|
||||
mod vorbis;
|
||||
#[cfg(feature = "wav")]
|
||||
|
@ -17,15 +19,15 @@ mod wav;
|
|||
/// Source of audio samples from decoding a file.
|
||||
///
|
||||
/// Supports WAV, Vorbis and Flac.
|
||||
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
|
||||
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis", feature = "mp3"))]
|
||||
pub struct Decoder<R>(DecoderImpl<R>)
|
||||
where
|
||||
R: Read + Seek;
|
||||
|
||||
#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis")))]
|
||||
#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis", feature = "mp3")))]
|
||||
pub struct Decoder<R>(::std::marker::PhantomData<R>);
|
||||
|
||||
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
|
||||
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis", feature = "mp3"))]
|
||||
enum DecoderImpl<R>
|
||||
where
|
||||
R: Read + Seek,
|
||||
|
@ -36,6 +38,8 @@ where
|
|||
Vorbis(vorbis::VorbisDecoder<R>),
|
||||
#[cfg(feature = "flac")]
|
||||
Flac(flac::FlacDecoder<R>),
|
||||
#[cfg(feature = "mp3")]
|
||||
Mp3(mp3::Mp3Decoder<R>),
|
||||
}
|
||||
|
||||
impl<R> Decoder<R>
|
||||
|
@ -71,11 +75,19 @@ where
|
|||
},
|
||||
};
|
||||
|
||||
#[cfg(feature = "mp3")]
|
||||
let data = match mp3::Mp3Decoder::new(data) {
|
||||
Err(data) => data,
|
||||
Ok(decoder) => {
|
||||
return Ok(Decoder(DecoderImpl::Mp3(decoder)));
|
||||
},
|
||||
};
|
||||
|
||||
Err(DecoderError::UnrecognizedFormat)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis")))]
|
||||
#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis", feature = "mp3")))]
|
||||
impl<R> Iterator for Decoder<R>
|
||||
where
|
||||
R: Read + Seek,
|
||||
|
@ -87,7 +99,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
|
||||
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis", feature = "mp3"))]
|
||||
impl<R> Iterator for Decoder<R>
|
||||
where
|
||||
R: Read + Seek,
|
||||
|
@ -103,6 +115,8 @@ where
|
|||
DecoderImpl::Vorbis(ref mut source) => source.next(),
|
||||
#[cfg(feature = "flac")]
|
||||
DecoderImpl::Flac(ref mut source) => source.next(),
|
||||
#[cfg(feature = "mp3")]
|
||||
DecoderImpl::Mp3(ref mut source) => source.next(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,11 +129,13 @@ where
|
|||
DecoderImpl::Vorbis(ref source) => source.size_hint(),
|
||||
#[cfg(feature = "flac")]
|
||||
DecoderImpl::Flac(ref source) => source.size_hint(),
|
||||
#[cfg(feature = "mp3")]
|
||||
DecoderImpl::Mp3(ref source) => source.size_hint(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis")))]
|
||||
#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis", feature = "mp3")))]
|
||||
impl<R> Source for Decoder<R>
|
||||
where
|
||||
R: Read + Seek,
|
||||
|
@ -138,7 +154,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
|
||||
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis", feature = "mp3"))]
|
||||
impl<R> Source for Decoder<R>
|
||||
where
|
||||
R: Read + Seek,
|
||||
|
@ -152,6 +168,8 @@ where
|
|||
DecoderImpl::Vorbis(ref source) => source.current_frame_len(),
|
||||
#[cfg(feature = "flac")]
|
||||
DecoderImpl::Flac(ref source) => source.current_frame_len(),
|
||||
#[cfg(feature = "mp3")]
|
||||
DecoderImpl::Mp3(ref source) => source.current_frame_len(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,6 +182,8 @@ where
|
|||
DecoderImpl::Vorbis(ref source) => source.channels(),
|
||||
#[cfg(feature = "flac")]
|
||||
DecoderImpl::Flac(ref source) => source.channels(),
|
||||
#[cfg(feature = "mp3")]
|
||||
DecoderImpl::Mp3(ref source) => source.channels(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,6 +196,8 @@ where
|
|||
DecoderImpl::Vorbis(ref source) => source.sample_rate(),
|
||||
#[cfg(feature = "flac")]
|
||||
DecoderImpl::Flac(ref source) => source.sample_rate(),
|
||||
#[cfg(feature = "mp3")]
|
||||
DecoderImpl::Mp3(ref source) => source.sample_rate(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,6 +210,8 @@ where
|
|||
DecoderImpl::Vorbis(ref source) => source.total_duration(),
|
||||
#[cfg(feature = "flac")]
|
||||
DecoderImpl::Flac(ref source) => source.total_duration(),
|
||||
#[cfg(feature = "mp3")]
|
||||
DecoderImpl::Mp3(ref source) => source.total_duration(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
79
src/decoder/mp3.rs
Normal file
79
src/decoder/mp3.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
use std::io::{Read, Seek};
|
||||
use std::time::Duration;
|
||||
|
||||
use Source;
|
||||
|
||||
use minimp3::{Decoder, Frame};
|
||||
|
||||
pub struct Mp3Decoder<R>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
decoder: Decoder<R>,
|
||||
current_frame: Frame,
|
||||
current_frame_offset: usize,
|
||||
}
|
||||
|
||||
impl<R> Mp3Decoder<R>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
pub fn new(data: R) -> Result<Self, ()> {
|
||||
let mut decoder = Decoder::new(data);
|
||||
let current_frame = decoder.next_frame().map_err(|_| ())?;
|
||||
|
||||
Ok(Mp3Decoder {
|
||||
decoder,
|
||||
current_frame,
|
||||
current_frame_offset: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> Source for Mp3Decoder<R>
|
||||
where
|
||||
R: Read + Seek
|
||||
{
|
||||
#[inline]
|
||||
fn current_frame_len(&self) -> Option<usize> {
|
||||
Some(self.current_frame.data.len())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn channels(&self) -> u16 {
|
||||
self.current_frame.channels as _
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sample_rate(&self) -> u32 {
|
||||
self.current_frame.sample_rate as _
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn total_duration(&self) -> Option<Duration> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> Iterator for Mp3Decoder<R>
|
||||
where
|
||||
R: Read + Seek
|
||||
{
|
||||
type Item = i16;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<i16> {
|
||||
if self.current_frame_offset == self.current_frame.data.len() {
|
||||
self.current_frame_offset = 0;
|
||||
match self.decoder.next_frame() {
|
||||
Ok(frame) => self.current_frame = frame,
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
|
||||
let v = self.current_frame.data[self.current_frame_offset];
|
||||
self.current_frame_offset += 1;
|
||||
|
||||
return Some(v);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue