Remove unnecessary 'static bound and cleanup (#356)

* Remove unnecessary 'static bound and cleanup

The decoder had an unnecessary 'static bound. Additionally I noticed
that there's a lot of (clippy) warnings, so I cleaned up the code a bit
as well. There's a few warnings left, but a few of those require
breaking changes.

* Address Review Comments
This commit is contained in:
Christopher Serr 2021-03-06 18:46:52 +01:00 committed by GitHub
parent e1aea73ba0
commit 181da2994b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 255 additions and 311 deletions

View file

@ -13,8 +13,7 @@
use std::time::Duration; use std::time::Duration;
use std::vec::IntoIter as VecIntoIter; use std::vec::IntoIter as VecIntoIter;
use crate::source::Source; use crate::{Sample, Source};
use crate::Sample;
/// A buffer of samples treated as a source. /// A buffer of samples treated as a source.
pub struct SamplesBuffer<S> { pub struct SamplesBuffer<S> {
@ -32,9 +31,9 @@ where
/// ///
/// # Panic /// # Panic
/// ///
/// - Panicks if the number of channels is zero. /// - Panics if the number of channels is zero.
/// - Panicks if the samples rate is zero. /// - Panics if the samples rate is zero.
/// - Panicks if the length of the buffer is larger than approximatively 16 billion elements. /// - Panics if the length of the buffer is larger than approximately 16 billion elements.
/// This is because the calculation of the duration would overflow. /// This is because the calculation of the duration would overflow.
/// ///
pub fn new<D>(channels: u16, sample_rate: u32, data: D) -> SamplesBuffer<S> pub fn new<D>(channels: u16, sample_rate: u32, data: D) -> SamplesBuffer<S>
@ -55,9 +54,9 @@ where
SamplesBuffer { SamplesBuffer {
data: data.into_iter(), data: data.into_iter(),
channels: channels, channels,
sample_rate: sample_rate, sample_rate,
duration: duration, duration,
} }
} }
} }

View file

@ -1,5 +1,3 @@
use cpal;
/// Iterator that converts from a certain channel count to another. /// Iterator that converts from a certain channel count to another.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ChannelCountConverter<I> pub struct ChannelCountConverter<I>
@ -33,9 +31,9 @@ where
assert!(to >= 1); assert!(to >= 1);
ChannelCountConverter { ChannelCountConverter {
input: input, input,
from: from, from,
to: to, to,
sample_repeat: None, sample_repeat: None,
next_output_sample_pos: 0, next_output_sample_pos: 0,
} }

View file

@ -13,7 +13,7 @@ impl<I, O> DataConverter<I, O> {
#[inline] #[inline]
pub fn new(input: I) -> DataConverter<I, O> { pub fn new(input: I) -> DataConverter<I, O> {
DataConverter { DataConverter {
input: input, input,
marker: PhantomData, marker: PhantomData,
} }
} }

View file

@ -1,5 +1,4 @@
use crate::conversions::Sample; use crate::conversions::Sample;
use cpal;
use std::mem; use std::mem;
@ -39,7 +38,7 @@ where
/// ///
/// # Panic /// # Panic
/// ///
/// Panicks if `from` or `to` are equal to 0. /// Panics if `from` or `to` are equal to 0.
/// ///
#[inline] #[inline]
pub fn new( pub fn new(
@ -85,7 +84,7 @@ where
}; };
SampleRateConverter { SampleRateConverter {
input: input, input,
from: from / gcd, from: from / gcd,
to: to / gcd, to: to / gcd,
channels: num_channels, channels: num_channels,
@ -133,7 +132,7 @@ where
} }
// Short circuit if there are some samples waiting. // Short circuit if there are some samples waiting.
if self.output_buffer.len() >= 1 { if !self.output_buffer.is_empty() {
return Some(self.output_buffer.remove(0)); return Some(self.output_buffer.remove(0));
} }
@ -174,7 +173,7 @@ where
.zip(self.next_frame.iter()) .zip(self.next_frame.iter())
.enumerate() .enumerate()
{ {
let sample = Sample::lerp(cur.clone(), next.clone(), numerator, self.to); let sample = Sample::lerp(*cur, *next, numerator, self.to);
if off == 0 { if off == 0 {
result = Some(sample); result = Some(sample);
@ -192,7 +191,7 @@ where
debug_assert!(self.next_frame.is_empty()); debug_assert!(self.next_frame.is_empty());
// draining `self.current_frame` // draining `self.current_frame`
if self.current_frame.len() >= 1 { if !self.current_frame.is_empty() {
let r = Some(self.current_frame.remove(0)); let r = Some(self.current_frame.remove(0));
mem::swap(&mut self.output_buffer, &mut self.current_frame); mem::swap(&mut self.output_buffer, &mut self.current_frame);
self.current_frame.clear(); self.current_frame.clear();

View file

@ -1,3 +1,4 @@
use std::cmp::Ordering;
use std::io::{Read, Seek, SeekFrom}; use std::io::{Read, Seek, SeekFrom};
use std::mem; use std::mem;
use std::time::Duration; use std::time::Duration;
@ -35,7 +36,7 @@ where
let spec = reader.streaminfo(); let spec = reader.streaminfo();
Ok(FlacDecoder { Ok(FlacDecoder {
reader: reader, reader,
current_block: Vec::with_capacity( current_block: Vec::with_capacity(
spec.max_block_size as usize * spec.channels as usize, spec.max_block_size as usize * spec.channels as usize,
), ),
@ -96,12 +97,10 @@ where
+ self.current_block_off / self.channels as usize; + self.current_block_off / self.channels as usize;
let raw_val = self.current_block[real_offset]; let raw_val = self.current_block[real_offset];
self.current_block_off += 1; self.current_block_off += 1;
let real_val = if self.bits_per_sample == 16 { let real_val = match self.bits_per_sample.cmp(&16) {
raw_val as i16 Ordering::Less => (raw_val << (16 - self.bits_per_sample)) as i16,
} else if self.bits_per_sample < 16 { Ordering::Equal => raw_val as i16,
(raw_val << (16 - self.bits_per_sample)) as i16 Ordering::Greater => (raw_val >> (self.bits_per_sample - 16)) as i16,
} else {
(raw_val >> (self.bits_per_sample - 16)) as i16
}; };
return Some(real_val as i16); return Some(real_val as i16);
} }

View file

@ -2,9 +2,8 @@
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
use std::io::{Read, Seek};
#[allow(unused_imports)] #[allow(unused_imports)]
use std::io::SeekFrom; use std::io::{Read, Seek, SeekFrom};
use std::mem; use std::mem;
use std::time::Duration; use std::time::Duration;
@ -42,12 +41,12 @@ where
Flac(flac::FlacDecoder<R>), Flac(flac::FlacDecoder<R>),
#[cfg(feature = "mp3")] #[cfg(feature = "mp3")]
Mp3(mp3::Mp3Decoder<R>), Mp3(mp3::Mp3Decoder<R>),
None(::std::marker::PhantomData<R>) None(::std::marker::PhantomData<R>),
} }
impl<R> Decoder<R> impl<R> Decoder<R>
where where
R: Read + Seek + Send + 'static, R: Read + Seek + Send,
{ {
/// Builds a new decoder. /// Builds a new decoder.
/// ///
@ -131,7 +130,7 @@ where
impl<R> LoopedDecoder<R> impl<R> LoopedDecoder<R>
where where
R: Read + Seek + Send + 'static, R: Read + Seek + Send,
{ {
fn new(decoder: Decoder<R>) -> LoopedDecoder<R> { fn new(decoder: Decoder<R>) -> LoopedDecoder<R> {
Self(decoder.0) Self(decoder.0)
@ -146,30 +145,30 @@ where
#[inline] #[inline]
fn next(&mut self) -> Option<i16> { fn next(&mut self) -> Option<i16> {
match self.0 { match &mut self.0 {
#[cfg(feature = "wav")] #[cfg(feature = "wav")]
DecoderImpl::Wav(ref mut source) => source.next(), DecoderImpl::Wav(source) => source.next(),
#[cfg(feature = "vorbis")] #[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref mut source) => source.next(), DecoderImpl::Vorbis(source) => source.next(),
#[cfg(feature = "flac")] #[cfg(feature = "flac")]
DecoderImpl::Flac(ref mut source) => source.next(), DecoderImpl::Flac(source) => source.next(),
#[cfg(feature = "mp3")] #[cfg(feature = "mp3")]
DecoderImpl::Mp3(ref mut source) => source.next(), DecoderImpl::Mp3(source) => source.next(),
DecoderImpl::None(_) => None, DecoderImpl::None(_) => None,
} }
} }
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
match self.0 { match &self.0 {
#[cfg(feature = "wav")] #[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.size_hint(), DecoderImpl::Wav(source) => source.size_hint(),
#[cfg(feature = "vorbis")] #[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.size_hint(), DecoderImpl::Vorbis(source) => source.size_hint(),
#[cfg(feature = "flac")] #[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.size_hint(), DecoderImpl::Flac(source) => source.size_hint(),
#[cfg(feature = "mp3")] #[cfg(feature = "mp3")]
DecoderImpl::Mp3(ref source) => source.size_hint(), DecoderImpl::Mp3(source) => source.size_hint(),
DecoderImpl::None(_) => (0, None), DecoderImpl::None(_) => (0, None),
} }
} }
@ -181,60 +180,60 @@ where
{ {
#[inline] #[inline]
fn current_frame_len(&self) -> Option<usize> { fn current_frame_len(&self) -> Option<usize> {
match self.0 { match &self.0 {
#[cfg(feature = "wav")] #[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.current_frame_len(), DecoderImpl::Wav(source) => source.current_frame_len(),
#[cfg(feature = "vorbis")] #[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.current_frame_len(), DecoderImpl::Vorbis(source) => source.current_frame_len(),
#[cfg(feature = "flac")] #[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.current_frame_len(), DecoderImpl::Flac(source) => source.current_frame_len(),
#[cfg(feature = "mp3")] #[cfg(feature = "mp3")]
DecoderImpl::Mp3(ref source) => source.current_frame_len(), DecoderImpl::Mp3(source) => source.current_frame_len(),
DecoderImpl::None(_) => Some(0), DecoderImpl::None(_) => Some(0),
} }
} }
#[inline] #[inline]
fn channels(&self) -> u16 { fn channels(&self) -> u16 {
match self.0 { match &self.0 {
#[cfg(feature = "wav")] #[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.channels(), DecoderImpl::Wav(source) => source.channels(),
#[cfg(feature = "vorbis")] #[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.channels(), DecoderImpl::Vorbis(source) => source.channels(),
#[cfg(feature = "flac")] #[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.channels(), DecoderImpl::Flac(source) => source.channels(),
#[cfg(feature = "mp3")] #[cfg(feature = "mp3")]
DecoderImpl::Mp3(ref source) => source.channels(), DecoderImpl::Mp3(source) => source.channels(),
DecoderImpl::None(_) => 0, DecoderImpl::None(_) => 0,
} }
} }
#[inline] #[inline]
fn sample_rate(&self) -> u32 { fn sample_rate(&self) -> u32 {
match self.0 { match &self.0 {
#[cfg(feature = "wav")] #[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.sample_rate(), DecoderImpl::Wav(source) => source.sample_rate(),
#[cfg(feature = "vorbis")] #[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.sample_rate(), DecoderImpl::Vorbis(source) => source.sample_rate(),
#[cfg(feature = "flac")] #[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.sample_rate(), DecoderImpl::Flac(source) => source.sample_rate(),
#[cfg(feature = "mp3")] #[cfg(feature = "mp3")]
DecoderImpl::Mp3(ref source) => source.sample_rate(), DecoderImpl::Mp3(source) => source.sample_rate(),
DecoderImpl::None(_) => 1, DecoderImpl::None(_) => 1,
} }
} }
#[inline] #[inline]
fn total_duration(&self) -> Option<Duration> { fn total_duration(&self) -> Option<Duration> {
match self.0 { match &self.0 {
#[cfg(feature = "wav")] #[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.total_duration(), DecoderImpl::Wav(source) => source.total_duration(),
#[cfg(feature = "vorbis")] #[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.total_duration(), DecoderImpl::Vorbis(source) => source.total_duration(),
#[cfg(feature = "flac")] #[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.total_duration(), DecoderImpl::Flac(source) => source.total_duration(),
#[cfg(feature = "mp3")] #[cfg(feature = "mp3")]
DecoderImpl::Mp3(ref source) => source.total_duration(), DecoderImpl::Mp3(source) => source.total_duration(),
DecoderImpl::None(_) => Some(Duration::default()), DecoderImpl::None(_) => Some(Duration::default()),
} }
} }
@ -248,15 +247,15 @@ where
#[inline] #[inline]
fn next(&mut self) -> Option<i16> { fn next(&mut self) -> Option<i16> {
if let Some(sample) = match self.0 { if let Some(sample) = match &mut self.0 {
#[cfg(feature = "wav")] #[cfg(feature = "wav")]
DecoderImpl::Wav(ref mut source) => source.next(), DecoderImpl::Wav(source) => source.next(),
#[cfg(feature = "vorbis")] #[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref mut source) => source.next(), DecoderImpl::Vorbis(source) => source.next(),
#[cfg(feature = "flac")] #[cfg(feature = "flac")]
DecoderImpl::Flac(ref mut source) => source.next(), DecoderImpl::Flac(source) => source.next(),
#[cfg(feature = "mp3")] #[cfg(feature = "mp3")]
DecoderImpl::Mp3(ref mut source) => source.next(), DecoderImpl::Mp3(source) => source.next(),
DecoderImpl::None(_) => None, DecoderImpl::None(_) => None,
} { } {
Some(sample) Some(sample)
@ -276,7 +275,9 @@ where
use lewton::inside_ogg::OggStreamReader; use lewton::inside_ogg::OggStreamReader;
let mut reader = source.into_inner().into_inner(); let mut reader = source.into_inner().into_inner();
reader.seek_bytes(SeekFrom::Start(0)).ok()?; reader.seek_bytes(SeekFrom::Start(0)).ok()?;
let mut source = vorbis::VorbisDecoder::from_stream_reader(OggStreamReader::from_ogg_reader(reader).ok()?); let mut source = vorbis::VorbisDecoder::from_stream_reader(
OggStreamReader::from_ogg_reader(reader).ok()?,
);
let sample = source.next(); let sample = source.next();
(DecoderImpl::Vorbis(source), sample) (DecoderImpl::Vorbis(source), sample)
} }
@ -296,7 +297,7 @@ where
let sample = source.next(); let sample = source.next();
(DecoderImpl::Mp3(source), sample) (DecoderImpl::Mp3(source), sample)
} }
none @ DecoderImpl::None(_) => (none, None) none @ DecoderImpl::None(_) => (none, None),
}; };
self.0 = decoder; self.0 = decoder;
sample sample
@ -305,15 +306,15 @@ where
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
match self.0 { match &self.0 {
#[cfg(feature = "wav")] #[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => (source.size_hint().0, None), DecoderImpl::Wav(source) => (source.size_hint().0, None),
#[cfg(feature = "vorbis")] #[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => (source.size_hint().0, None), DecoderImpl::Vorbis(source) => (source.size_hint().0, None),
#[cfg(feature = "flac")] #[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => (source.size_hint().0, None), DecoderImpl::Flac(source) => (source.size_hint().0, None),
#[cfg(feature = "mp3")] #[cfg(feature = "mp3")]
DecoderImpl::Mp3(ref source) => (source.size_hint().0, None), DecoderImpl::Mp3(source) => (source.size_hint().0, None),
DecoderImpl::None(_) => (0, None), DecoderImpl::None(_) => (0, None),
} }
} }
@ -325,45 +326,45 @@ where
{ {
#[inline] #[inline]
fn current_frame_len(&self) -> Option<usize> { fn current_frame_len(&self) -> Option<usize> {
match self.0 { match &self.0 {
#[cfg(feature = "wav")] #[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.current_frame_len(), DecoderImpl::Wav(source) => source.current_frame_len(),
#[cfg(feature = "vorbis")] #[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.current_frame_len(), DecoderImpl::Vorbis(source) => source.current_frame_len(),
#[cfg(feature = "flac")] #[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.current_frame_len(), DecoderImpl::Flac(source) => source.current_frame_len(),
#[cfg(feature = "mp3")] #[cfg(feature = "mp3")]
DecoderImpl::Mp3(ref source) => source.current_frame_len(), DecoderImpl::Mp3(source) => source.current_frame_len(),
DecoderImpl::None(_) => Some(0), DecoderImpl::None(_) => Some(0),
} }
} }
#[inline] #[inline]
fn channels(&self) -> u16 { fn channels(&self) -> u16 {
match self.0 { match &self.0 {
#[cfg(feature = "wav")] #[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.channels(), DecoderImpl::Wav(source) => source.channels(),
#[cfg(feature = "vorbis")] #[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.channels(), DecoderImpl::Vorbis(source) => source.channels(),
#[cfg(feature = "flac")] #[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.channels(), DecoderImpl::Flac(source) => source.channels(),
#[cfg(feature = "mp3")] #[cfg(feature = "mp3")]
DecoderImpl::Mp3(ref source) => source.channels(), DecoderImpl::Mp3(source) => source.channels(),
DecoderImpl::None(_) => 0, DecoderImpl::None(_) => 0,
} }
} }
#[inline] #[inline]
fn sample_rate(&self) -> u32 { fn sample_rate(&self) -> u32 {
match self.0 { match &self.0 {
#[cfg(feature = "wav")] #[cfg(feature = "wav")]
DecoderImpl::Wav(ref source) => source.sample_rate(), DecoderImpl::Wav(source) => source.sample_rate(),
#[cfg(feature = "vorbis")] #[cfg(feature = "vorbis")]
DecoderImpl::Vorbis(ref source) => source.sample_rate(), DecoderImpl::Vorbis(source) => source.sample_rate(),
#[cfg(feature = "flac")] #[cfg(feature = "flac")]
DecoderImpl::Flac(ref source) => source.sample_rate(), DecoderImpl::Flac(source) => source.sample_rate(),
#[cfg(feature = "mp3")] #[cfg(feature = "mp3")]
DecoderImpl::Mp3(ref source) => source.sample_rate(), DecoderImpl::Mp3(source) => source.sample_rate(),
DecoderImpl::None(_) => 1, DecoderImpl::None(_) => 1,
} }
} }
@ -384,7 +385,7 @@ pub enum DecoderError {
impl fmt::Display for DecoderError { impl fmt::Display for DecoderError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
&DecoderError::UnrecognizedFormat => write!(f, "Unrecognized format"), DecoderError::UnrecognizedFormat => write!(f, "Unrecognized format"),
} }
} }
} }
@ -392,7 +393,7 @@ impl fmt::Display for DecoderError {
impl Error for DecoderError { impl Error for DecoderError {
fn description(&self) -> &str { fn description(&self) -> &str {
match self { match self {
&DecoderError::UnrecognizedFormat => "Unrecognized format", DecoderError::UnrecognizedFormat => "Unrecognized format",
} }
} }
} }

View file

@ -77,6 +77,6 @@ where
let v = self.current_frame.data[self.current_frame_offset]; let v = self.current_frame.data[self.current_frame_offset];
self.current_frame_offset += 1; self.current_frame_offset += 1;
return Some(v); Some(v)
} }
} }

View file

@ -29,20 +29,19 @@ where
Ok(Self::from_stream_reader(stream_reader)) Ok(Self::from_stream_reader(stream_reader))
} }
pub fn from_stream_reader(mut stream_reader: OggStreamReader<R>) -> Self { pub fn from_stream_reader(mut stream_reader: OggStreamReader<R>) -> Self {
let mut data = match stream_reader.read_dec_packet_itl().ok().and_then(|v| v) { let mut data = match stream_reader.read_dec_packet_itl() {
Some(d) => d, Ok(Some(d)) => d,
None => Vec::new(), _ => Vec::new(),
}; };
// The first packet is always empty, therefore // The first packet is always empty, therefore
// we need to read the second frame to get some data // we need to read the second frame to get some data
match stream_reader.read_dec_packet_itl().ok().and_then(|v| v) { if let Ok(Some(mut d)) = stream_reader.read_dec_packet_itl() {
Some(mut d) => data.append(&mut d), data.append(&mut d);
None => (), }
};
VorbisDecoder { VorbisDecoder {
stream_reader: stream_reader, stream_reader,
current_data: data.into_iter(), current_data: data.into_iter(),
} }
} }
@ -86,26 +85,16 @@ where
fn next(&mut self) -> Option<i16> { fn next(&mut self) -> Option<i16> {
if let Some(sample) = self.current_data.next() { if let Some(sample) = self.current_data.next() {
if self.current_data.len() == 0 { if self.current_data.len() == 0 {
if let Some(data) = self if let Ok(Some(data)) = self.stream_reader.read_dec_packet_itl() {
.stream_reader
.read_dec_packet_itl()
.ok()
.and_then(|v| v)
{
self.current_data = data.into_iter(); self.current_data = data.into_iter();
} }
} }
return Some(sample); Some(sample)
} else { } else {
if let Some(data) = self if let Ok(Some(data)) = self.stream_reader.read_dec_packet_itl() {
.stream_reader
.read_dec_packet_itl()
.ok()
.and_then(|v| v)
{
self.current_data = data.into_iter(); self.current_data = data.into_iter();
} }
return self.current_data.next(); self.current_data.next()
} }
} }

View file

@ -28,12 +28,12 @@ where
let reader = WavReader::new(data).unwrap(); let reader = WavReader::new(data).unwrap();
let spec = reader.spec(); let spec = reader.spec();
let reader = SamplesIterator { let reader = SamplesIterator {
reader: reader, reader,
samples_read: 0, samples_read: 0,
}; };
Ok(WavDecoder { Ok(WavDecoder {
reader: reader, reader,
sample_rate: spec.sample_rate, sample_rate: spec.sample_rate,
channels: spec.channels, channels: spec.channels,
}) })

View file

@ -1,13 +1,10 @@
//! Mixer that plays multiple sounds at the same time. //! Mixer that plays multiple sounds at the same time.
use std::sync::atomic::AtomicBool; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::atomic::Ordering; use std::sync::{Arc, Mutex};
use std::sync::Arc;
use std::sync::Mutex;
use std::time::Duration; use std::time::Duration;
use crate::source::Source; use crate::source::{Source, UniformSourceIterator};
use crate::source::UniformSourceIterator;
use crate::Sample; use crate::Sample;
/// Builds a new mixer. /// Builds a new mixer.

View file

@ -20,19 +20,17 @@
//! use std::io::BufReader; //! use std::io::BufReader;
//! use rodio::Source; //! use rodio::Source;
//! //!
//! fn main() { //! let (stream, stream_handle) = rodio::OutputStream::try_default().unwrap();
//! let (stream, stream_handle) = rodio::OutputStream::try_default().unwrap();
//! //!
//! // Load a sound from a file, using a path relative to Cargo.toml //! // Load a sound from a file, using a path relative to Cargo.toml
//! let file = File::open("sound.ogg").unwrap(); //! let file = File::open("sound.ogg").unwrap();
//! let source = rodio::Decoder::new(BufReader::new(file)).unwrap(); //! let source = rodio::Decoder::new(BufReader::new(file)).unwrap();
//! stream_handle.play_raw(source.convert_samples()); //! stream_handle.play_raw(source.convert_samples());
//! //!
//! // The sound plays in a separate audio thread, //! // The sound plays in a separate audio thread,
//! // so we need to keep the main thread alive while it's playing. //! // so we need to keep the main thread alive while it's playing.
//! // Press ctrl + C to stop the process once you're done. //! // Press ctrl + C to stop the process once you're done.
//! loop {} //! loop {}
//! }
//! ``` //! ```
//! //!
//! ## Sink //! ## Sink

View file

@ -1,17 +1,11 @@
//! Queue that plays sounds one after the other. //! Queue that plays sounds one after the other.
use std::sync::atomic::AtomicBool; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::atomic::Ordering; use std::sync::mpsc::{Receiver, Sender};
use std::sync::mpsc; use std::sync::{mpsc, Arc, Mutex};
use std::sync::mpsc::Receiver;
use std::sync::mpsc::Sender;
use std::sync::Arc;
use std::sync::Mutex;
use std::time::Duration; use std::time::Duration;
use crate::source::Empty; use crate::source::{Empty, Source, Zero};
use crate::source::Source;
use crate::source::Zero;
use crate::Sample; use crate::Sample;
/// Builds a new queue. It consists of an input and an output. /// Builds a new queue. It consists of an input and an output.

View file

@ -1,15 +1,10 @@
use crate::stream::{OutputStreamHandle, PlayError}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::atomic::Ordering;
use std::sync::atomic::{AtomicBool, AtomicUsize};
use std::sync::mpsc::Receiver; use std::sync::mpsc::Receiver;
use std::sync::Arc; use std::sync::{Arc, Mutex};
use std::sync::Mutex;
use std::time::Duration; use std::time::Duration;
use crate::queue; use crate::stream::{OutputStreamHandle, PlayError};
use crate::source::Done; use crate::{queue, source::Done, Sample, Source};
use crate::Sample;
use crate::Source;
/// Handle to an device that outputs sounds. /// Handle to an device that outputs sounds.
/// ///
@ -179,8 +174,7 @@ impl Drop for Sink {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::buffer::SamplesBuffer; use crate::buffer::SamplesBuffer;
use crate::sink::Sink; use crate::{Sink, Source};
use crate::source::Source;
#[test] #[test]
fn test_pause_and_stop() { fn test_pause_and_stop() {
@ -192,7 +186,7 @@ mod tests {
// Low rate to ensure immediate control. // Low rate to ensure immediate control.
sink.append(SamplesBuffer::new(1, 1, v.clone())); sink.append(SamplesBuffer::new(1, 1, v.clone()));
let mut src = SamplesBuffer::new(1, 1, v.clone()).convert_samples(); let mut src = SamplesBuffer::new(1, 1, v).convert_samples();
assert_eq!(queue_rx.next(), src.next()); assert_eq!(queue_rx.next(), src.next());
assert_eq!(queue_rx.next(), src.next()); assert_eq!(queue_rx.next(), src.next());

View file

@ -1,7 +1,6 @@
use std::time::Duration; use std::time::Duration;
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
/// Internal function that builds a `Amplify` object. /// Internal function that builds a `Amplify` object.
pub fn amplify<I>(input: I, factor: f32) -> Amplify<I> pub fn amplify<I>(input: I, factor: f32) -> Amplify<I>
@ -9,10 +8,7 @@ where
I: Source, I: Source,
I::Item: Sample, I::Item: Sample,
{ {
Amplify { Amplify { input, factor }
input: input,
factor: factor,
}
} }
/// Filter that modifies each sample by a given value. /// Filter that modifies each sample by a given value.

View file

@ -11,8 +11,8 @@ where
I: Source<Item = f32>, I: Source<Item = f32>,
{ {
BltFilter { BltFilter {
input: input, input,
formula: BltFormula::LowPass { freq: freq, q: 0.5 }, formula: BltFormula::LowPass { freq, q: 0.5 },
applier: None, applier: None,
x_n1: 0.0, x_n1: 0.0,
x_n2: 0.0, x_n2: 0.0,
@ -35,7 +35,7 @@ pub struct BltFilter<I> {
impl<I> BltFilter<I> { impl<I> BltFilter<I> {
/// Modifies this filter so that it becomes a low-pass filter. /// Modifies this filter so that it becomes a low-pass filter.
pub fn to_low_pass(&mut self, freq: u32) { pub fn to_low_pass(&mut self, freq: u32) {
self.formula = BltFormula::LowPass { freq: freq, q: 0.5 }; self.formula = BltFormula::LowPass { freq, q: 0.5 };
self.applier = None; self.applier = None;
} }
@ -135,8 +135,8 @@ enum BltFormula {
impl BltFormula { impl BltFormula {
fn to_applier(&self, sampling_frequency: u32) -> BltApplier { fn to_applier(&self, sampling_frequency: u32) -> BltApplier {
match self { match *self {
&BltFormula::LowPass { freq, q } => { BltFormula::LowPass { freq, q } => {
let w0 = 2.0 * PI * freq as f32 / sampling_frequency as f32; let w0 = 2.0 * PI * freq as f32 / sampling_frequency as f32;
let alpha = w0.sin() / (2.0 * q); let alpha = w0.sin() / (2.0 * q);

View file

@ -2,8 +2,7 @@ use std::cmp;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::Duration; use std::time::Duration;
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
/// Internal function that builds a `Buffered` object. /// Internal function that builds a `Buffered` object.
#[inline] #[inline]
@ -18,7 +17,7 @@ where
Buffered { Buffered {
current_frame: first_frame, current_frame: first_frame,
position_in_frame: 0, position_in_frame: 0,
total_duration: total_duration, total_duration,
} }
} }
@ -90,9 +89,9 @@ where
} }
Arc::new(Frame::Data(FrameData { Arc::new(Frame::Data(FrameData {
data: data, data,
channels: channels, channels,
rate: rate, rate,
next: Mutex::new(Arc::new(Frame::Input(Mutex::new(Some(input))))), next: Mutex::new(Arc::new(Frame::Input(Mutex::new(Some(input))))),
})) }))
} }
@ -106,14 +105,14 @@ where
fn next_frame(&mut self) { fn next_frame(&mut self) {
let next_frame = { let next_frame = {
let mut next_frame_ptr = match &*self.current_frame { let mut next_frame_ptr = match &*self.current_frame {
&Frame::Data(FrameData { ref next, .. }) => next.lock().unwrap(), Frame::Data(FrameData { next, .. }) => next.lock().unwrap(),
_ => unreachable!(), _ => unreachable!(),
}; };
let next_frame = match &**next_frame_ptr { let next_frame = match &**next_frame_ptr {
&Frame::Data(_) => next_frame_ptr.clone(), Frame::Data(_) => next_frame_ptr.clone(),
&Frame::End => next_frame_ptr.clone(), Frame::End => next_frame_ptr.clone(),
&Frame::Input(ref input) => { Frame::Input(input) => {
let input = input.lock().unwrap().take().unwrap(); let input = input.lock().unwrap().take().unwrap();
extract(input) extract(input)
} }
@ -141,18 +140,18 @@ where
let advance_frame; let advance_frame;
match &*self.current_frame { match &*self.current_frame {
&Frame::Data(FrameData { ref data, .. }) => { Frame::Data(FrameData { data, .. }) => {
current_sample = Some(data[self.position_in_frame].clone()); current_sample = Some(data[self.position_in_frame]);
self.position_in_frame += 1; self.position_in_frame += 1;
advance_frame = self.position_in_frame >= data.len(); advance_frame = self.position_in_frame >= data.len();
} }
&Frame::End => { Frame::End => {
current_sample = None; current_sample = None;
advance_frame = false; advance_frame = false;
} }
&Frame::Input(_) => unreachable!(), Frame::Input(_) => unreachable!(),
}; };
if advance_frame { if advance_frame {
@ -181,27 +180,27 @@ where
#[inline] #[inline]
fn current_frame_len(&self) -> Option<usize> { fn current_frame_len(&self) -> Option<usize> {
match &*self.current_frame { match &*self.current_frame {
&Frame::Data(FrameData { ref data, .. }) => Some(data.len() - self.position_in_frame), Frame::Data(FrameData { data, .. }) => Some(data.len() - self.position_in_frame),
&Frame::End => Some(0), Frame::End => Some(0),
&Frame::Input(_) => unreachable!(), Frame::Input(_) => unreachable!(),
} }
} }
#[inline] #[inline]
fn channels(&self) -> u16 { fn channels(&self) -> u16 {
match &*self.current_frame { match *self.current_frame {
&Frame::Data(FrameData { channels, .. }) => channels, Frame::Data(FrameData { channels, .. }) => channels,
&Frame::End => 1, Frame::End => 1,
&Frame::Input(_) => unreachable!(), Frame::Input(_) => unreachable!(),
} }
} }
#[inline] #[inline]
fn sample_rate(&self) -> u32 { fn sample_rate(&self) -> u32 {
match &*self.current_frame { match *self.current_frame {
&Frame::Data(FrameData { rate, .. }) => rate, Frame::Data(FrameData { rate, .. }) => rate,
&Frame::End => 44100, Frame::End => 44100,
&Frame::Input(_) => unreachable!(), Frame::Input(_) => unreachable!(),
} }
} }
@ -220,8 +219,8 @@ where
fn clone(&self) -> Buffered<I> { fn clone(&self) -> Buffered<I> {
Buffered { Buffered {
current_frame: self.current_frame.clone(), current_frame: self.current_frame.clone(),
position_in_frame: self.position_in_frame.clone(), position_in_frame: self.position_in_frame,
total_duration: self.total_duration.clone(), total_duration: self.total_duration,
} }
} }
} }

View file

@ -1,7 +1,7 @@
use crate::Sample;
use crate::Source;
use std::time::Duration; use std::time::Duration;
use crate::{Sample, Source};
/// Combines channels in input into a single mono source, then plays that mono sound /// Combines channels in input into a single mono source, then plays that mono sound
/// to each channel at the volume given for that channel. /// to each channel at the volume given for that channel.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -33,7 +33,7 @@ where
if let Some(s) = input.next() { if let Some(s) = input.next() {
sample = Some( sample = Some(
sample sample
.get_or_insert_with(|| I::Item::zero_value()) .get_or_insert_with(I::Item::zero_value)
.saturating_add(s), .saturating_add(s),
); );
} }
@ -92,13 +92,13 @@ where
if let Some(s) = self.input.next() { if let Some(s) = self.input.next() {
self.current_sample = Some( self.current_sample = Some(
self.current_sample self.current_sample
.get_or_insert_with(|| I::Item::zero_value()) .get_or_insert_with(I::Item::zero_value)
.saturating_add(s), .saturating_add(s),
); );
} }
} }
} }
return ret; ret
} }
#[inline] #[inline]

View file

@ -1,8 +1,7 @@
use std::time::Duration; use std::time::Duration;
use crate::source::{FadeIn, Mix, TakeDuration}; use crate::source::{FadeIn, Mix, TakeDuration};
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
/// Mixes one sound fading out with another sound fading in for the given duration. /// Mixes one sound fading out with another sound fading in for the given duration.
/// ///
@ -32,8 +31,7 @@ mod tests {
use crate::buffer::SamplesBuffer; use crate::buffer::SamplesBuffer;
fn dummysource(length: u8) -> SamplesBuffer<f32> { fn dummysource(length: u8) -> SamplesBuffer<f32> {
let data: Vec<f32> = (1..=length).map(f32::from).collect(); let data: Vec<f32> = (1..=length).map(f32::from).collect();
let source = SamplesBuffer::new(1, 1, data); SamplesBuffer::new(1, 1, data)
source
} }
#[test] #[test]

View file

@ -1,7 +1,6 @@
use std::time::Duration; use std::time::Duration;
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
/// Internal function that builds a `Delay` object. /// Internal function that builds a `Delay` object.
pub fn delay<I>(input: I, duration: Duration) -> Delay<I> pub fn delay<I>(input: I, duration: Duration) -> Delay<I>
@ -13,7 +12,7 @@ where
let samples = duration_ns * input.sample_rate() as u64 / 1000000000 * input.channels() as u64; let samples = duration_ns * input.sample_rate() as u64 / 1000000000 * input.channels() as u64;
Delay { Delay {
input: input, input,
remaining_samples: samples as usize, remaining_samples: samples as usize,
requested_duration: duration, requested_duration: duration,
} }

View file

@ -1,9 +1,9 @@
use crate::Sample;
use crate::Source;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use crate::{Sample, Source};
/// When the inner source is empty this decrements an `AtomicUsize`. /// When the inner source is empty this decrements an `AtomicUsize`.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Done<I> { pub struct Done<I> {

View file

@ -1,12 +1,19 @@
use crate::Sample;
use crate::Source;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::time::Duration; use std::time::Duration;
use crate::{Sample, Source};
/// An empty source. /// An empty source.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct Empty<S>(PhantomData<S>); pub struct Empty<S>(PhantomData<S>);
impl<S> Default for Empty<S> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<S> Empty<S> { impl<S> Empty<S> {
#[inline] #[inline]
pub fn new() -> Empty<S> { pub fn new() -> Empty<S> {

View file

@ -1,7 +1,6 @@
use std::time::Duration; use std::time::Duration;
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
/// Internal function that builds a `FadeIn` object. /// Internal function that builds a `FadeIn` object.
pub fn fadein<I>(input: I, duration: Duration) -> FadeIn<I> pub fn fadein<I>(input: I, duration: Duration) -> FadeIn<I>
@ -12,7 +11,7 @@ where
let duration = duration.as_secs() * 1000000000 + duration.subsec_nanos() as u64; let duration = duration.as_secs() * 1000000000 + duration.subsec_nanos() as u64;
FadeIn { FadeIn {
input: input, input,
remaining_ns: duration as f32, remaining_ns: duration as f32,
total_ns: duration as f32, total_ns: duration as f32,
} }

View file

@ -1,5 +1,4 @@
use crate::source::from_iter; use crate::source::{from_iter, FromIter};
use crate::source::FromIter;
/// Builds a source that chains sources built from a factory. /// Builds a source that chains sources built from a factory.
/// ///
@ -12,7 +11,7 @@ pub fn from_factory<F, S>(factory: F) -> FromIter<FromFactoryIter<F>>
where where
F: FnMut() -> Option<S>, F: FnMut() -> Option<S>,
{ {
from_iter(FromFactoryIter { factory: factory }) from_iter(FromFactoryIter { factory })
} }
/// Internal type used by `from_factory`. /// Internal type used by `from_factory`.

View file

@ -1,7 +1,6 @@
use std::time::Duration; use std::time::Duration;
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
/// Builds a source that chains sources provided by an iterator. /// Builds a source that chains sources provided by an iterator.
/// ///
@ -18,7 +17,7 @@ where
let first_source = iterator.next(); let first_source = iterator.next();
FromIter { FromIter {
iterator: iterator, iterator,
current_source: first_source, current_source: first_source,
} }
} }
@ -46,7 +45,7 @@ where
#[inline] #[inline]
fn next(&mut self) -> Option<<I::Item as Iterator>::Item> { fn next(&mut self) -> Option<<I::Item as Iterator>::Item> {
loop { loop {
if let Some(ref mut src) = self.current_source { if let Some(src) = &mut self.current_source {
if let Some(value) = src.next() { if let Some(value) = src.next() {
return Some(value); return Some(value);
} }
@ -62,7 +61,7 @@ where
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
if let Some(ref cur) = self.current_source { if let Some(cur) = &self.current_source {
(cur.size_hint().0, None) (cur.size_hint().0, None)
} else { } else {
(0, None) (0, None)
@ -91,7 +90,7 @@ where
const THRESHOLD: usize = 10240; const THRESHOLD: usize = 10240;
// Try the current `current_frame_len`. // Try the current `current_frame_len`.
if let Some(ref src) = self.current_source { if let Some(src) = &self.current_source {
if let Some(val) = src.current_frame_len() { if let Some(val) = src.current_frame_len() {
if val != 0 { if val != 0 {
return Some(val); return Some(val);
@ -100,7 +99,7 @@ where
} }
// Try the size hint. // Try the size hint.
if let Some(ref src) = self.current_source { if let Some(src) = &self.current_source {
if let Some(val) = src.size_hint().1 { if let Some(val) = src.size_hint().1 {
if val < THRESHOLD && val != 0 { if val < THRESHOLD && val != 0 {
return Some(val); return Some(val);
@ -114,7 +113,7 @@ where
#[inline] #[inline]
fn channels(&self) -> u16 { fn channels(&self) -> u16 {
if let Some(ref src) = self.current_source { if let Some(src) = &self.current_source {
src.channels() src.channels()
} else { } else {
// Dummy value that only happens if the iterator was empty. // Dummy value that only happens if the iterator was empty.
@ -124,7 +123,7 @@ where
#[inline] #[inline]
fn sample_rate(&self) -> u32 { fn sample_rate(&self) -> u32 {
if let Some(ref src) = self.current_source { if let Some(src) = &self.current_source {
src.sample_rate() src.sample_rate()
} else { } else {
// Dummy value that only happens if the iterator was empty. // Dummy value that only happens if the iterator was empty.
@ -141,8 +140,7 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::buffer::SamplesBuffer; use crate::buffer::SamplesBuffer;
use crate::source::from_iter; use crate::source::{from_iter, Source};
use crate::source::Source;
#[test] #[test]
fn basic() { fn basic() {

View file

@ -2,9 +2,7 @@ use std::cmp;
use std::time::Duration; use std::time::Duration;
use crate::source::uniform::UniformSourceIterator; use crate::source::uniform::UniformSourceIterator;
use crate::{Sample, Source};
use crate::Sample;
use crate::Source;
/// Internal function that builds a `Mix` object. /// Internal function that builds a `Mix` object.
pub fn mix<I1, I2>(input1: I1, input2: I2) -> Mix<I1, I2> pub fn mix<I1, I2>(input1: I1, input2: I2) -> Mix<I1, I2>

View file

@ -1,7 +1,6 @@
use std::time::Duration; use std::time::Duration;
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
/// Internal function that builds a `Pausable` object. /// Internal function that builds a `Pausable` object.
pub fn pausable<I>(source: I, paused: bool) -> Pausable<I> pub fn pausable<I>(source: I, paused: bool) -> Pausable<I>

View file

@ -1,7 +1,6 @@
use std::time::Duration; use std::time::Duration;
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
/// Internal function that builds a `PeriodicAccess` object. /// Internal function that builds a `PeriodicAccess` object.
pub fn periodic<I, F>(source: I, period: Duration, modifier: F) -> PeriodicAccess<I, F> pub fn periodic<I, F>(source: I, period: Duration, modifier: F) -> PeriodicAccess<I, F>
@ -11,12 +10,12 @@ where
{ {
// TODO: handle the fact that the samples rate can change // TODO: handle the fact that the samples rate can change
// TODO: generally, just wrong // TODO: generally, just wrong
let update_ms = period.as_secs() as u32 * 1_000 + period.subsec_nanos() / 1_000_000; let update_ms = period.as_secs() as u32 * 1_000 + period.subsec_millis();
let update_frequency = (update_ms * source.sample_rate()) / 1000 * source.channels() as u32; let update_frequency = (update_ms * source.sample_rate()) / 1000 * source.channels() as u32;
PeriodicAccess { PeriodicAccess {
input: source, input: source,
modifier: modifier, modifier,
// Can overflow when subtracting if this is 0 // Can overflow when subtracting if this is 0
update_frequency: if update_frequency == 0 { update_frequency: if update_frequency == 0 {
1 1
@ -122,11 +121,12 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::buffer::SamplesBuffer;
use crate::source::Source;
use std::cell::RefCell; use std::cell::RefCell;
use std::time::Duration; use std::time::Duration;
use crate::buffer::SamplesBuffer;
use crate::source::Source;
#[test] #[test]
fn stereo_access() { fn stereo_access() {
// Stereo, 1Hz audio buffer // Stereo, 1Hz audio buffer

View file

@ -2,8 +2,7 @@ use std::time::Duration;
use crate::source::buffered::Buffered; use crate::source::buffered::Buffered;
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
/// Internal function that builds a `Repeat` object. /// Internal function that builds a `Repeat` object.
pub fn repeat<I>(input: I) -> Repeat<I> pub fn repeat<I>(input: I) -> Repeat<I>

View file

@ -1,8 +1,7 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use std::time::Duration; use std::time::Duration;
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
use cpal::Sample as CpalSample; use cpal::Sample as CpalSample;
/// An iterator that reads from a `Source` and converts the samples to a specific rate and /// An iterator that reads from a `Source` and converts the samples to a specific rate and

View file

@ -1,6 +1,8 @@
use crate::Source; use std::f32::consts::PI;
use std::time::Duration; use std::time::Duration;
use crate::Source;
/// An infinite source that produces a sine. /// An infinite source that produces a sine.
/// ///
/// Always has a rate of 48kHz and one channel. /// Always has a rate of 48kHz and one channel.
@ -28,7 +30,7 @@ impl Iterator for SineWave {
fn next(&mut self) -> Option<f32> { fn next(&mut self) -> Option<f32> {
self.num_sample = self.num_sample.wrapping_add(1); self.num_sample = self.num_sample.wrapping_add(1);
let value = 2.0 * 3.14159265 * self.freq * self.num_sample as f32 / 48000.0; let value = 2.0 * PI * self.freq * self.num_sample as f32 / 48000.0;
Some(value.sin()) Some(value.sin())
} }
} }

View file

@ -1,6 +1,7 @@
use crate::{Sample, Source};
use std::time::Duration; use std::time::Duration;
use crate::{Sample, Source};
const NS_PER_SECOND: u128 = 1_000_000_000; const NS_PER_SECOND: u128 = 1_000_000_000;
/// Internal function that builds a `SkipDuration` object. /// Internal function that builds a `SkipDuration` object.
@ -147,16 +148,17 @@ where
fn total_duration(&self) -> Option<Duration> { fn total_duration(&self) -> Option<Duration> {
self.input.total_duration().map(|val| { self.input.total_duration().map(|val| {
val.checked_sub(self.skipped_duration) val.checked_sub(self.skipped_duration)
.unwrap_or(Duration::from_secs(0)) .unwrap_or_else(|| Duration::from_secs(0))
}) })
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::time::Duration;
use crate::buffer::SamplesBuffer; use crate::buffer::SamplesBuffer;
use crate::source::Source; use crate::source::Source;
use std::time::Duration;
fn test_skip_duration_samples_left( fn test_skip_duration_samples_left(
channels: u16, channels: u16,
@ -168,7 +170,7 @@ mod tests {
.map(|_| 0f32) .map(|_| 0f32)
.collect(); .collect();
let test_buffer = SamplesBuffer::new(channels, sample_rate, data); let test_buffer = SamplesBuffer::new(channels, sample_rate, data);
let seconds_left = seconds.checked_sub(seconds_to_skip).unwrap_or(0); let seconds_left = seconds.saturating_sub(seconds_to_skip);
let samples_left_expected = (sample_rate * channels as u32 * seconds_left) as usize; let samples_left_expected = (sample_rate * channels as u32 * seconds_left) as usize;
let samples_left = test_buffer let samples_left = test_buffer

View file

@ -1,9 +1,9 @@
use crate::source::ChannelVolume;
use crate::Sample;
use crate::Source;
use std::fmt::Debug; use std::fmt::Debug;
use std::time::Duration; use std::time::Duration;
use crate::source::ChannelVolume;
use crate::{Sample, Source};
/// Combines channels in input into a single mono source, then plays that mono sound /// Combines channels in input into a single mono source, then plays that mono sound
/// to each channel at the volume given for that channel. /// to each channel at the volume given for that channel.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]

View file

@ -1,14 +1,10 @@
use std::time::Duration; use std::time::Duration;
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
/// Internal function that builds a `Speed` object. /// Internal function that builds a `Speed` object.
pub fn speed<I>(input: I, factor: f32) -> Speed<I> { pub fn speed<I>(input: I, factor: f32) -> Speed<I> {
Speed { Speed { input, factor }
input: input,
factor: factor,
}
} }
/// Filter that modifies each sample by a given value. /// Filter that modifies each sample by a given value.

View file

@ -1,7 +1,6 @@
use std::time::Duration; use std::time::Duration;
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
/// Internal function that builds a `Stoppable` object. /// Internal function that builds a `Stoppable` object.
pub fn stoppable<I>(source: I) -> Stoppable<I> { pub fn stoppable<I>(source: I) -> Stoppable<I> {

View file

@ -1,7 +1,6 @@
use std::time::Duration; use std::time::Duration;
use crate::Sample; use crate::{Sample, Source};
use crate::Source;
/// Internal function that builds a `TakeDuration` object. /// Internal function that builds a `TakeDuration` object.
pub fn take_duration<I>(input: I, duration: Duration) -> TakeDuration<I> pub fn take_duration<I>(input: I, duration: Duration) -> TakeDuration<I>
@ -12,7 +11,7 @@ where
TakeDuration { TakeDuration {
current_frame_len: input.current_frame_len(), current_frame_len: input.current_frame_len(),
duration_per_sample: TakeDuration::get_duration_per_sample(&input), duration_per_sample: TakeDuration::get_duration_per_sample(&input),
input: input, input,
remaining_duration: duration, remaining_duration: duration,
requested_duration: duration, requested_duration: duration,
filter: None, filter: None,
@ -119,19 +118,17 @@ where
if self.remaining_duration <= self.duration_per_sample { if self.remaining_duration <= self.duration_per_sample {
None None
} else if let Some(sample) = self.input.next() {
let sample = match &self.filter {
Some(filter) => filter.apply(sample, &self),
None => sample,
};
self.remaining_duration -= self.duration_per_sample;
Some(sample)
} else { } else {
if let Some(sample) = self.input.next() { None
let sample = match &self.filter {
Some(filter) => filter.apply(sample, &self),
None => sample,
};
self.remaining_duration = self.remaining_duration - self.duration_per_sample;
Some(sample)
} else {
None
}
} }
} }

View file

@ -1,14 +1,8 @@
use std::cmp; use std::cmp;
use std::time::Duration; use std::time::Duration;
use cpal; use crate::conversions::{ChannelCountConverter, DataConverter, SampleRateConverter};
use crate::{Sample, Source};
use crate::conversions::ChannelCountConverter;
use crate::conversions::DataConverter;
use crate::conversions::SampleRateConverter;
use crate::Sample;
use crate::Source;
/// An iterator that reads from a `Source` and converts the samples to a specific rate and /// An iterator that reads from a `Source` and converts the samples to a specific rate and
/// channels count. /// channels count.
@ -45,9 +39,9 @@ where
UniformSourceIterator { UniformSourceIterator {
inner: Some(input), inner: Some(input),
target_channels: target_channels, target_channels,
target_sample_rate: target_sample_rate, target_sample_rate,
total_duration: total_duration, total_duration,
} }
} }
@ -74,9 +68,8 @@ where
from_channels, from_channels,
); );
let input = ChannelCountConverter::new(input, from_channels, target_channels); let input = ChannelCountConverter::new(input, from_channels, target_channels);
let input = DataConverter::new(input);
input DataConverter::new(input)
} }
} }
@ -158,7 +151,7 @@ where
#[inline] #[inline]
fn next(&mut self) -> Option<<I as Iterator>::Item> { fn next(&mut self) -> Option<<I as Iterator>::Item> {
if let Some(ref mut n) = self.n { if let Some(n) = &mut self.n {
if *n != 0 { if *n != 0 {
*n -= 1; *n -= 1;
self.iter.next() self.iter.next()

View file

@ -1,8 +1,8 @@
use crate::Sample;
use crate::Source;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::time::Duration; use std::time::Duration;
use crate::{Sample, Source};
/// An infinite source that produces zero. /// An infinite source that produces zero.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Zero<S> { pub struct Zero<S> {
@ -15,8 +15,8 @@ impl<S> Zero<S> {
#[inline] #[inline]
pub fn new(channels: u16, sample_rate: u32) -> Zero<S> { pub fn new(channels: u16, sample_rate: u32) -> Zero<S> {
Zero { Zero {
channels: channels, channels,
sample_rate: sample_rate, sample_rate,
marker: PhantomData, marker: PhantomData,
} }
} }

View file

@ -1,13 +1,12 @@
use crate::source::Spatial;
use crate::stream::{OutputStreamHandle, PlayError};
use crate::Sample;
use crate::Sink;
use crate::Source;
use std::f32; use std::f32;
use std::fmt::Debug; use std::fmt::Debug;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::Duration; use std::time::Duration;
use crate::source::Spatial;
use crate::stream::{OutputStreamHandle, PlayError};
use crate::{Sample, Sink, Source};
pub struct SpatialSink { pub struct SpatialSink {
sink: Sink, sink: Sink,
positions: Arc<Mutex<SoundPositions>>, positions: Arc<Mutex<SoundPositions>>,

View file

@ -13,8 +13,7 @@
use std::slice::Iter as SliceIter; use std::slice::Iter as SliceIter;
use std::time::Duration; use std::time::Duration;
use crate::source::Source; use crate::{Sample, Source};
use crate::Sample;
/// A buffer of samples treated as a source. /// A buffer of samples treated as a source.
#[derive(Clone)] #[derive(Clone)]
@ -36,9 +35,9 @@ where
/// ///
/// # Panic /// # Panic
/// ///
/// - Panicks if the number of channels is zero. /// - Panics if the number of channels is zero.
/// - Panicks if the samples rate is zero. /// - Panics if the samples rate is zero.
/// - Panicks if the length of the buffer is larger than approximatively 16 billion elements. /// - Panics if the length of the buffer is larger than approximatively 16 billion elements.
/// This is because the calculation of the duration would overflow. /// This is because the calculation of the duration would overflow.
/// ///
pub fn new(channels: u16, sample_rate: u32, data: &'static [S]) -> StaticSamplesBuffer<S> { pub fn new(channels: u16, sample_rate: u32, data: &'static [S]) -> StaticSamplesBuffer<S> {
@ -55,9 +54,9 @@ where
StaticSamplesBuffer { StaticSamplesBuffer {
data: data.iter(), data: data.iter(),
channels: channels, channels,
sample_rate: sample_rate, sample_rate,
duration: duration, duration,
} }
} }
} }

View file

@ -1,14 +1,13 @@
use std::io::{Read, Seek};
use std::sync::{Arc, Weak};
use std::{error, fmt};
use crate::decoder; use crate::decoder;
use crate::dynamic_mixer::{self, DynamicMixerController}; use crate::dynamic_mixer::{self, DynamicMixerController};
use crate::sink::Sink; use crate::sink::Sink;
use crate::source::Source; use crate::source::Source;
use cpal::{ use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
traits::{DeviceTrait, HostTrait, StreamTrait}, use cpal::Sample;
Sample,
};
use std::io::{Read, Seek};
use std::sync::{Arc, Weak};
use std::{error, fmt};
/// `cpal::Stream` container. Also see the more useful `OutputStreamHandle`. /// `cpal::Stream` container. Also see the more useful `OutputStreamHandle`.
/// ///