rodio/src/decoder/wav.rs

174 lines
4.2 KiB
Rust
Raw Normal View History

2015-07-22 12:23:03 +00:00
use std::io::{Read, Seek, SeekFrom};
2015-10-16 12:02:44 +00:00
use std::time::Duration;
use Source;
2015-07-22 10:14:11 +00:00
use hound::{SampleFormat, WavReader};
2015-07-22 10:14:11 +00:00
2015-10-22 18:21:07 +00:00
/// Decoder for the WAV format.
2017-02-01 09:14:50 +00:00
pub struct WavDecoder<R>
2018-04-19 08:03:48 +00:00
where
R: Read + Seek,
2017-02-01 09:14:50 +00:00
{
reader: SamplesIterator<R>,
sample_rate: u32,
channels: u16,
2015-07-22 10:14:11 +00:00
}
2017-02-01 09:14:50 +00:00
impl<R> WavDecoder<R>
2018-04-19 08:03:48 +00:00
where
R: Read + Seek,
2017-02-01 09:14:50 +00:00
{
2015-10-22 18:21:07 +00:00
/// Attempts to decode the data as WAV.
pub fn new(mut data: R) -> Result<WavDecoder<R>, R> {
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();
2017-02-01 09:14:50 +00:00
let reader = SamplesIterator {
reader: reader,
samples_read: 0,
};
2015-09-01 17:35:26 +00:00
2015-07-22 10:14:11 +00:00
Ok(WavDecoder {
2018-04-19 08:03:48 +00:00
reader: reader,
sample_rate: spec.sample_rate,
channels: spec.channels,
})
2015-07-22 10:14:11 +00:00
}
}
2017-02-01 09:14:50 +00:00
struct SamplesIterator<R>
2018-04-19 08:03:48 +00:00
where
R: Read + Seek,
2017-02-01 09:14:50 +00:00
{
2015-09-10 18:25:13 +00:00
reader: WavReader<R>,
samples_read: u32,
}
2017-02-01 09:14:50 +00:00
impl<R> Iterator for SamplesIterator<R>
2018-04-19 08:03:48 +00:00
where
R: Read + Seek,
2017-02-01 09:14:50 +00:00
{
2015-09-10 18:25:13 +00:00
type Item = i16;
#[inline]
fn next(&mut self) -> Option<i16> {
let spec = self.reader.spec();
match (spec.sample_format, spec.bits_per_sample) {
(SampleFormat::Float, 32) => self.reader.samples().next().map(|value| {
self.samples_read += 1;
f32_to_i16(value.unwrap_or(0.0))
}),
(SampleFormat::Int, 16) => self.reader.samples().next().map(|value| {
self.samples_read += 1;
value.unwrap_or(0)
}),
(SampleFormat::Int, 24) => self.reader.samples().next().map(|value| {
self.samples_read += 1;
i24_to_i16(value.unwrap_or(0))
}),
(sample_format, bits_per_sample) => panic!(
"Unimplemented wav spec: {:?}, {}",
sample_format, bits_per_sample
),
2015-09-10 18:25:13 +00:00
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = (self.reader.len() - self.samples_read) as usize;
(len, Some(len))
}
}
2017-07-03 08:09:10 +00:00
impl<R> ExactSizeIterator for SamplesIterator<R>
2018-04-19 08:03:48 +00:00
where
R: Read + Seek,
2017-07-03 08:09:10 +00:00
{
}
2015-09-10 18:25:13 +00:00
2017-02-01 09:14:50 +00:00
impl<R> Source for WavDecoder<R>
2018-04-19 08:03:48 +00:00
where
R: Read + Seek,
2017-02-01 09:14:50 +00:00
{
#[inline]
2017-05-01 09:11:33 +00:00
fn current_frame_len(&self) -> Option<usize> {
2015-10-16 12:02:44 +00:00
None
}
#[inline]
2017-05-01 09:11:33 +00:00
fn channels(&self) -> u16 {
self.channels
}
#[inline]
fn sample_rate(&self) -> u32 {
self.sample_rate
2015-09-23 08:47:15 +00:00
}
2015-10-16 12:02:44 +00:00
#[inline]
2017-05-01 09:11:33 +00:00
fn total_duration(&self) -> Option<Duration> {
let ms = self.len() * 1000 / (self.channels as usize * self.sample_rate as usize);
2015-10-16 12:02:44 +00:00
Some(Duration::from_millis(ms as u64))
}
}
2015-09-23 08:47:15 +00:00
2017-02-01 09:14:50 +00:00
impl<R> Iterator for WavDecoder<R>
2018-04-19 08:03:48 +00:00
where
R: Read + Seek,
2017-02-01 09:14:50 +00:00
{
type Item = i16;
#[inline]
fn next(&mut self) -> Option<i16> {
self.reader.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.reader.size_hint()
}
2015-07-22 10:14:11 +00:00
}
2017-07-03 08:09:10 +00:00
impl<R> ExactSizeIterator for WavDecoder<R>
2018-04-19 08:03:48 +00:00
where
R: Read + Seek,
2017-07-03 08:09:10 +00:00
{
}
2015-10-22 18:21:07 +00:00
/// Returns true if the stream contains WAV data, then resets it to where it was.
2017-02-01 09:14:50 +00:00
fn is_wave<R>(mut data: R) -> bool
2018-04-19 08:03:48 +00:00
where
R: Read + Seek,
2017-02-01 09:14:50 +00:00
{
2015-10-22 18:21:07 +00:00
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 false;
}
data.seek(SeekFrom::Start(stream_pos)).unwrap();
true
}
/// Returns a 32 bit WAV float as an i16. WAV floats are typically in the range of
/// [-1.0, 1.0] while i16s are in the range [-32768, 32767]. Note that this
/// function definitely causes precision loss but hopefully this isn't too
/// audiable when actually playing?
fn f32_to_i16(f: f32) -> i16 {
// prefer to clip the input rather than be excessively loud.
(f.max(-1.0).min(1.0) * i16::max_value() as f32) as i16
}
/// Returns a 24 bit WAV int as an i16. Note that this is a 24 bit integer, not a
/// 32 bit one. 24 bit ints are in the range [8,388,608, 8,388,607] while i16s
/// are in the range [-32768, 32767]. Note that this function definitely causes
/// precision loss but hopefully this isn't too audiable when actually playing?
fn i24_to_i16(i: i32) -> i16 {
(i >> 8) as i16
}