mirror of
https://github.com/RustAudio/rodio
synced 2024-12-13 05:32:32 +00:00
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:
parent
e1aea73ba0
commit
181da2994b
40 changed files with 255 additions and 311 deletions
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
|
|
@ -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.
|
||||
|
|
20
src/lib.rs
20
src/lib.rs
|
@ -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
|
||||
|
|
14
src/queue.rs
14
src/queue.rs
|
@ -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.
|
||||
|
|
18
src/sink.rs
18
src/sink.rs
|
@ -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());
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>>,
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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`.
|
||||
///
|
||||
|
|
Loading…
Reference in a new issue