rodio/src/decoder/wav.rs

101 lines
2.7 KiB
Rust
Raw Normal View History

2015-07-22 12:23:03 +00:00
use std::io::{Read, Seek, SeekFrom};
2015-09-11 11:49:07 +00:00
use std::cmp;
2015-07-22 10:14:11 +00:00
use super::Decoder;
2015-09-11 13:43:00 +00:00
use conversions;
2015-07-22 10:14:11 +00:00
2015-09-01 17:35:26 +00:00
use cpal::{self, Endpoint, Voice};
2015-07-22 10:14:11 +00:00
use hound::WavReader;
2015-09-01 17:35:26 +00:00
pub struct WavDecoder {
reader: Box<Iterator<Item=f32> + Send>,
2015-09-23 08:47:15 +00:00
total_duration_ms: u32,
2015-07-22 10:14:11 +00:00
}
2015-09-01 17:35:26 +00:00
impl WavDecoder {
pub fn new<R>(mut data: R, output_channels: u16, output_samples_rate: u32)
-> Result<WavDecoder, R>
2015-09-10 15:20:42 +00:00
where R: Read + Seek + Send + 'static
{
2015-09-01 17:35:26 +00:00
if !is_wave(data.by_ref()) {
2015-07-22 12:23:03 +00:00
return Err(data);
}
let reader = WavReader::new(data).unwrap();
2015-07-22 10:14:11 +00:00
let spec = reader.spec();
2015-09-23 08:47:15 +00:00
let total_duration_ms = reader.duration() * 1000 / spec.sample_rate;
2015-07-22 10:14:11 +00:00
2015-09-10 18:25:13 +00:00
let reader = SamplesIterator { reader: reader, samples_read: 0 };
let reader = conversions::ChannelsCountConverter::new(reader, spec.channels, 2);
2015-09-01 17:35:26 +00:00
let reader = conversions::SamplesRateConverter::new(reader, cpal::SamplesRate(spec.sample_rate),
cpal::SamplesRate(output_samples_rate), output_channels);
let reader = conversions::DataConverter::new(reader);
2015-09-01 17:35:26 +00:00
2015-07-22 10:14:11 +00:00
Ok(WavDecoder {
reader: Box::new(reader),
2015-09-23 08:47:15 +00:00
total_duration_ms: total_duration_ms,
2015-07-22 10:14:11 +00:00
})
}
}
2015-09-10 18:25:13 +00:00
struct SamplesIterator<R> where R: Read + Seek {
reader: WavReader<R>,
samples_read: u32,
}
impl<R> Iterator for SamplesIterator<R> where R: Read + Seek {
type Item = i16;
#[inline]
fn next(&mut self) -> Option<i16> {
if let Some(value) = self.reader.samples().next() {
self.samples_read += 1;
Some(value.unwrap_or(0))
} else {
None
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = (self.reader.len() - self.samples_read) as usize;
(len, Some(len))
}
}
impl<R> ExactSizeIterator for SamplesIterator<R> where R: Read + Seek {}
2015-09-01 17:35:26 +00:00
/// Returns true if the stream contains WAV data, then resets it to where it was.
fn is_wave<R>(mut data: R) -> bool where R: Read + Seek {
let stream_pos = data.seek(SeekFrom::Current(0)).unwrap();
2015-07-22 10:14:11 +00:00
2015-09-01 17:35:26 +00:00
if WavReader::new(data.by_ref()).is_err() {
data.seek(SeekFrom::Start(stream_pos)).unwrap();
return false;
}
2015-07-22 10:14:11 +00:00
2015-09-01 17:35:26 +00:00
data.seek(SeekFrom::Start(stream_pos)).unwrap();
true
}
impl Decoder for WavDecoder {
2015-09-23 08:47:15 +00:00
fn get_total_duration_ms(&self) -> u32 {
self.total_duration_ms
}
}
2015-09-23 08:47:15 +00:00
impl Iterator for WavDecoder {
type Item = f32;
#[inline]
fn next(&mut self) -> Option<f32> {
self.reader.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.reader.size_hint()
}
2015-07-22 10:14:11 +00:00
}
impl ExactSizeIterator for WavDecoder {}