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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,17 +1,11 @@
//! Queue that plays sounds one after the other.
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use std::sync::mpsc;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::Sender;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{Receiver, Sender};
use std::sync::{mpsc, Arc, Mutex};
use std::time::Duration;
use crate::source::Empty;
use crate::source::Source;
use crate::source::Zero;
use crate::source::{Empty, Source, Zero};
use crate::Sample;
/// 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::Ordering;
use std::sync::atomic::{AtomicBool, AtomicUsize};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::mpsc::Receiver;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use crate::queue;
use crate::source::Done;
use crate::Sample;
use crate::Source;
use crate::stream::{OutputStreamHandle, PlayError};
use crate::{queue, source::Done, Sample, Source};
/// Handle to an device that outputs sounds.
///
@ -179,8 +174,7 @@ impl Drop for Sink {
#[cfg(test)]
mod tests {
use crate::buffer::SamplesBuffer;
use crate::sink::Sink;
use crate::source::Source;
use crate::{Sink, Source};
#[test]
fn test_pause_and_stop() {
@ -192,7 +186,7 @@ mod tests {
// Low rate to ensure immediate control.
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());

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,7 +1,6 @@
use std::time::Duration;
use crate::Sample;
use crate::Source;
use crate::{Sample, Source};
/// Internal function that builds a `Delay` object.
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;
Delay {
input: input,
input,
remaining_samples: samples as usize,
requested_duration: duration,
}

View file

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

View file

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

View file

@ -1,7 +1,6 @@
use std::time::Duration;
use crate::Sample;
use crate::Source;
use crate::{Sample, Source};
/// Internal function that builds a `FadeIn` object.
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;
FadeIn {
input: input,
input,
remaining_ns: duration as f32,
total_ns: duration as f32,
}

View file

@ -1,5 +1,4 @@
use crate::source::from_iter;
use crate::source::FromIter;
use crate::source::{from_iter, FromIter};
/// 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
F: FnMut() -> Option<S>,
{
from_iter(FromFactoryIter { factory: factory })
from_iter(FromFactoryIter { factory })
}
/// Internal type used by `from_factory`.

View file

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

View file

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

View file

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

View file

@ -1,7 +1,6 @@
use std::time::Duration;
use crate::Sample;
use crate::Source;
use crate::{Sample, Source};
/// Internal function that builds a `PeriodicAccess` object.
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: 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;
PeriodicAccess {
input: source,
modifier: modifier,
modifier,
// Can overflow when subtracting if this is 0
update_frequency: if update_frequency == 0 {
1
@ -122,11 +121,12 @@ where
#[cfg(test)]
mod tests {
use crate::buffer::SamplesBuffer;
use crate::source::Source;
use std::cell::RefCell;
use std::time::Duration;
use crate::buffer::SamplesBuffer;
use crate::source::Source;
#[test]
fn stereo_access() {
// Stereo, 1Hz audio buffer

View file

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

View file

@ -1,8 +1,7 @@
use std::marker::PhantomData;
use std::time::Duration;
use crate::Sample;
use crate::Source;
use crate::{Sample, Source};
use cpal::Sample as CpalSample;
/// 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 crate::Source;
/// An infinite source that produces a sine.
///
/// Always has a rate of 48kHz and one channel.
@ -28,7 +30,7 @@ impl Iterator for SineWave {
fn next(&mut self) -> Option<f32> {
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())
}
}

View file

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

View file

@ -1,9 +1,9 @@
use crate::source::ChannelVolume;
use crate::Sample;
use crate::Source;
use std::fmt::Debug;
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
/// to each channel at the volume given for that channel.
#[derive(Clone, Debug)]

View file

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

View file

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

View file

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

View file

@ -1,14 +1,8 @@
use std::cmp;
use std::time::Duration;
use cpal;
use crate::conversions::ChannelCountConverter;
use crate::conversions::DataConverter;
use crate::conversions::SampleRateConverter;
use crate::Sample;
use crate::Source;
use crate::conversions::{ChannelCountConverter, DataConverter, SampleRateConverter};
use crate::{Sample, Source};
/// An iterator that reads from a `Source` and converts the samples to a specific rate and
/// channels count.
@ -45,9 +39,9 @@ where
UniformSourceIterator {
inner: Some(input),
target_channels: target_channels,
target_sample_rate: target_sample_rate,
total_duration: total_duration,
target_channels,
target_sample_rate,
total_duration,
}
}
@ -74,9 +68,8 @@ where
from_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]
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 {
*n -= 1;
self.iter.next()

View file

@ -1,8 +1,8 @@
use crate::Sample;
use crate::Source;
use std::marker::PhantomData;
use std::time::Duration;
use crate::{Sample, Source};
/// An infinite source that produces zero.
#[derive(Clone, Debug)]
pub struct Zero<S> {
@ -15,8 +15,8 @@ impl<S> Zero<S> {
#[inline]
pub fn new(channels: u16, sample_rate: u32) -> Zero<S> {
Zero {
channels: channels,
sample_rate: sample_rate,
channels,
sample_rate,
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::fmt::Debug;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use crate::source::Spatial;
use crate::stream::{OutputStreamHandle, PlayError};
use crate::{Sample, Sink, Source};
pub struct SpatialSink {
sink: Sink,
positions: Arc<Mutex<SoundPositions>>,

View file

@ -13,8 +13,7 @@
use std::slice::Iter as SliceIter;
use std::time::Duration;
use crate::source::Source;
use crate::Sample;
use crate::{Sample, Source};
/// A buffer of samples treated as a source.
#[derive(Clone)]
@ -36,9 +35,9 @@ where
///
/// # Panic
///
/// - Panicks if the number of channels is zero.
/// - Panicks if the samples rate is zero.
/// - Panicks if the length of the buffer is larger than approximatively 16 billion elements.
/// - Panics if the number of channels is zero.
/// - Panics if the samples rate is zero.
/// - Panics if the length of the buffer is larger than approximatively 16 billion elements.
/// This is because the calculation of the duration would overflow.
///
pub fn new(channels: u16, sample_rate: u32, data: &'static [S]) -> StaticSamplesBuffer<S> {
@ -55,9 +54,9 @@ where
StaticSamplesBuffer {
data: data.iter(),
channels: channels,
sample_rate: sample_rate,
duration: duration,
channels,
sample_rate,
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::dynamic_mixer::{self, DynamicMixerController};
use crate::sink::Sink;
use crate::source::Source;
use cpal::{
traits::{DeviceTrait, HostTrait, StreamTrait},
Sample,
};
use std::io::{Read, Seek};
use std::sync::{Arc, Weak};
use std::{error, fmt};
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use cpal::Sample;
/// `cpal::Stream` container. Also see the more useful `OutputStreamHandle`.
///