mirror of
https://github.com/RustAudio/rodio
synced 2025-01-09 02:08:41 +00:00
51 lines
1.4 KiB
Rust
51 lines
1.4 KiB
Rust
use std::io::{Read, Seek, SeekFrom};
|
|
use super::Decoder;
|
|
|
|
use cpal::{self, Voice};
|
|
use hound::WavReader;
|
|
use hound::WavSpec;
|
|
|
|
pub struct WavDecoder<R> where R: Read {
|
|
reader: WavReader<R>,
|
|
spec: WavSpec,
|
|
}
|
|
|
|
impl<R> WavDecoder<R> where R: Read + Seek {
|
|
pub fn new(mut data: R) -> Result<WavDecoder<R>, R> {
|
|
let stream_pos = data.seek(SeekFrom::Current(0)).unwrap();
|
|
|
|
if WavReader::new(data.by_ref()).is_err() {
|
|
data.seek(SeekFrom::Start(stream_pos)).unwrap();
|
|
return Err(data);
|
|
}
|
|
|
|
data.seek(SeekFrom::Start(stream_pos)).unwrap();
|
|
let reader = WavReader::new(data).unwrap();
|
|
let spec = reader.spec();
|
|
|
|
Ok(WavDecoder {
|
|
reader: reader,
|
|
spec: spec,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl<R> Decoder for WavDecoder<R> where R: Read {
|
|
fn write(&mut self, voice: &mut Voice) {
|
|
let mut samples = self.reader.samples::<i16>();
|
|
let samples_left = samples.len();
|
|
if samples_left == 0 { return; }
|
|
|
|
// TODO: hack because of a bug in cpal
|
|
let samples_left = if samples_left > 512 { 512 } else { samples_left };
|
|
|
|
let mut buffer: cpal::Buffer<i16> =
|
|
voice.append_data(self.spec.channels,
|
|
cpal::SamplesRate(self.spec.sample_rate),
|
|
samples_left);
|
|
|
|
for (dest, src) in buffer.iter_mut().zip(&mut samples) {
|
|
*dest = src.unwrap();
|
|
}
|
|
}
|
|
}
|