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;
|
2015-09-27 08:41:46 +00:00
|
|
|
|
|
2015-10-16 11:35:30 +00:00
|
|
|
|
use Source;
|
2015-07-22 10:14:11 +00:00
|
|
|
|
|
2018-11-09 20:58:43 +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
|
|
|
|
{
|
2015-10-16 11:35:30 +00:00
|
|
|
|
reader: SamplesIterator<R>,
|
2018-04-18 12:24:33 +00:00
|
|
|
|
sample_rate: u32,
|
2015-10-16 11:35:30 +00:00
|
|
|
|
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.
|
2015-10-16 11:35:30 +00:00
|
|
|
|
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> {
|
2018-11-09 20:58:43 +00:00
|
|
|
|
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
|
|
|
|
{
|
2015-10-16 11:35:30 +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
|
2015-10-16 11:35:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2017-05-01 09:11:33 +00:00
|
|
|
|
fn channels(&self) -> u16 {
|
2015-10-16 11:35:30 +00:00
|
|
|
|
self.channels
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2018-04-18 12:24:33 +00:00
|
|
|
|
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> {
|
2018-04-18 12:24:33 +00:00
|
|
|
|
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-27 07:56:29 +00:00
|
|
|
|
}
|
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
|
|
|
|
{
|
2015-10-16 11:35:30 +00:00
|
|
|
|
type Item = i16;
|
2015-09-23 08:33:45 +00:00
|
|
|
|
|
2015-09-27 07:56:29 +00:00
|
|
|
|
#[inline]
|
2015-10-16 11:35:30 +00:00
|
|
|
|
fn next(&mut self) -> Option<i16> {
|
2015-09-27 07:56:29 +00:00
|
|
|
|
self.reader.next()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
|
|
|
self.reader.size_hint()
|
2015-09-23 08:33:45 +00:00
|
|
|
|
}
|
2015-07-22 10:14:11 +00:00
|
|
|
|
}
|
2015-09-27 07:56:29 +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
|
|
|
|
|
}
|
2018-11-09 20:58:43 +00:00
|
|
|
|
|
|
|
|
|
/// 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
|
|
|
|
|
}
|