2015-07-22 12:23:03 +00:00
|
|
|
use std::io::{Read, Seek, SeekFrom};
|
2015-07-22 10:14:11 +00:00
|
|
|
use super::Decoder;
|
2015-09-01 17:35:26 +00:00
|
|
|
use super::conversions;
|
2015-07-22 10:14:11 +00:00
|
|
|
|
2015-09-01 17:35:26 +00:00
|
|
|
use cpal::{self, Endpoint, Voice};
|
|
|
|
use hound::WavIntoSamples;
|
2015-07-22 10:14:11 +00:00
|
|
|
use hound::WavReader;
|
|
|
|
use hound::WavSpec;
|
|
|
|
|
2015-09-01 17:35:26 +00:00
|
|
|
pub struct WavDecoder {
|
|
|
|
reader: Box<Iterator<Item=i16> + Send>,
|
|
|
|
voice: Voice,
|
2015-07-22 10:14:11 +00:00
|
|
|
}
|
|
|
|
|
2015-09-01 17:35:26 +00:00
|
|
|
impl WavDecoder {
|
|
|
|
pub fn new<R>(endpoint: &Endpoint, mut data: R) -> Result<WavDecoder, R> where R: Read + Seek + Send + 'static {
|
|
|
|
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-01 17:35:26 +00:00
|
|
|
let voice_format = endpoint.get_supported_formats_list().unwrap().next().unwrap();
|
|
|
|
let voice = Voice::new(endpoint, &voice_format).unwrap();
|
|
|
|
|
|
|
|
let reader = reader.into_samples().map(|s| s.unwrap_or(0));
|
|
|
|
let reader = conversions::ChannelsCountConverter::new(reader, spec.channels,
|
|
|
|
voice.get_channels());
|
|
|
|
let reader = conversions::SamplesRateConverter::new(reader, cpal::SamplesRate(spec.sample_rate),
|
|
|
|
voice.get_samples_rate());
|
|
|
|
|
2015-07-22 10:14:11 +00:00
|
|
|
Ok(WavDecoder {
|
2015-09-01 17:35:26 +00:00
|
|
|
reader: Box::new(reader),
|
|
|
|
voice: voice,
|
2015-07-22 10:14:11 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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 {
|
|
|
|
fn write(&mut self) {
|
|
|
|
let (min, _) = self.reader.size_hint();
|
2015-07-22 10:14:11 +00:00
|
|
|
|
2015-09-01 17:35:26 +00:00
|
|
|
if min == 0 {
|
|
|
|
// finished
|
|
|
|
return;
|
2015-07-22 10:14:11 +00:00
|
|
|
}
|
2015-09-01 17:35:26 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
let mut buffer = self.voice.append_data(min);
|
|
|
|
conversions::convert_and_write(self.reader.by_ref(), &mut buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
self.voice.play();
|
2015-07-22 10:14:11 +00:00
|
|
|
}
|
|
|
|
}
|