Merge pull request #164 from frazar/master

Refactor code with `cargo fmt`
This commit is contained in:
Pierre Krieger 2018-04-21 11:10:28 +02:00 committed by GitHub
commit 6ab1c2a6b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 673 additions and 473 deletions

View file

@ -6,10 +6,12 @@ use std::time::Duration;
fn main() {
let device = rodio::default_output_device().unwrap();
let mut sink = rodio::SpatialSink::new(&device,
[-10.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[-1.0, 0.0, 0.0]);
let mut sink = rodio::SpatialSink::new(
&device,
[-10.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[-1.0, 0.0, 0.0],
);
let file = std::fs::File::open("examples/music.ogg").unwrap();
let source = rodio::Decoder::new(BufReader::new(file)).unwrap();

View file

@ -26,7 +26,8 @@ pub struct SamplesBuffer<S> {
}
impl<S> SamplesBuffer<S>
where S: Sample
where
S: Sample,
{
/// Builds a new `SamplesBuffer`.
///
@ -38,16 +39,19 @@ impl<S> SamplesBuffer<S>
/// This is because the calculation of the duration would overflow.
///
pub fn new<D>(channels: u16, sample_rate: u32, data: D) -> SamplesBuffer<S>
where D: Into<Vec<S>>
where
D: Into<Vec<S>>,
{
assert!(channels != 0);
assert!(sample_rate != 0);
let data = data.into();
let duration_ns = 1_000_000_000u64.checked_mul(data.len() as u64).unwrap() /
sample_rate as u64 / channels as u64;
let duration = Duration::new(duration_ns / 1_000_000_000,
(duration_ns % 1_000_000_000) as u32);
let duration_ns = 1_000_000_000u64.checked_mul(data.len() as u64).unwrap()
/ sample_rate as u64 / channels as u64;
let duration = Duration::new(
duration_ns / 1_000_000_000,
(duration_ns % 1_000_000_000) as u32,
);
SamplesBuffer {
data: data.into_iter(),
@ -59,7 +63,8 @@ impl<S> SamplesBuffer<S>
}
impl<S> Source for SamplesBuffer<S>
where S: Sample
where
S: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
@ -83,7 +88,8 @@ impl<S> Source for SamplesBuffer<S>
}
impl<S> Iterator for SamplesBuffer<S>
where S: Sample
where
S: Sample,
{
type Item = S;

View file

@ -3,7 +3,8 @@ use cpal;
/// Iterator that converts from a certain channel count to another.
#[derive(Clone, Debug)]
pub struct ChannelCountConverter<I>
where I: Iterator
where
I: Iterator,
{
input: I,
from: cpal::ChannelCount,
@ -13,7 +14,8 @@ pub struct ChannelCountConverter<I>
}
impl<I> ChannelCountConverter<I>
where I: Iterator
where
I: Iterator,
{
/// Initializes the iterator.
///
@ -22,8 +24,9 @@ impl<I> ChannelCountConverter<I>
/// Panicks if `from` or `to` are equal to 0.
///
#[inline]
pub fn new(input: I, from: cpal::ChannelCount, to: cpal::ChannelCount)
-> ChannelCountConverter<I> {
pub fn new(
input: I, from: cpal::ChannelCount, to: cpal::ChannelCount,
) -> ChannelCountConverter<I> {
assert!(from >= 1);
assert!(to >= 1);
@ -44,8 +47,9 @@ impl<I> ChannelCountConverter<I>
}
impl<I> Iterator for ChannelCountConverter<I>
where I: Iterator,
I::Item: Clone
where
I: Iterator,
I::Item: Clone,
{
type Item = I::Item;
@ -79,20 +83,20 @@ impl<I> Iterator for ChannelCountConverter<I>
fn size_hint(&self) -> (usize, Option<usize>) {
let (min, max) = self.input.size_hint();
let min = (min / self.from as usize) * self.to as usize +
self.next_output_sample_pos as usize;
let min =
(min / self.from as usize) * self.to as usize + self.next_output_sample_pos as usize;
let max = max.map(|max| {
(max / self.from as usize) * self.to as usize +
self.next_output_sample_pos as usize
});
(max / self.from as usize) * self.to as usize + self.next_output_sample_pos as usize
});
(min, max)
}
}
impl<I> ExactSizeIterator for ChannelCountConverter<I>
where I: ExactSizeIterator,
I::Item: Clone
where
I: ExactSizeIterator,
I::Item: Clone,
{
}

View file

@ -1,4 +1,3 @@
use cpal::Sample as CpalSample;
use std::marker::PhantomData;
@ -27,9 +26,10 @@ impl<I, O> DataConverter<I, O> {
}
impl<I, O> Iterator for DataConverter<I, O>
where I: Iterator,
I::Item: Sample,
O: Sample
where
I: Iterator,
I::Item: Sample,
O: Sample,
{
type Item = O;
@ -45,9 +45,10 @@ impl<I, O> Iterator for DataConverter<I, O>
}
impl<I, O> ExactSizeIterator for DataConverter<I, O>
where I: ExactSizeIterator,
I::Item: Sample,
O: Sample
where
I: ExactSizeIterator,
I::Item: Sample,
O: Sample,
{
}
@ -105,8 +106,8 @@ impl Sample for u16 {
impl Sample for i16 {
#[inline]
fn lerp(first: i16, second: i16, numerator: u32, denominator: u32) -> i16 {
(first as i32 + (second as i32 - first as i32) * numerator as i32 / denominator as i32) as
i16
(first as i32 + (second as i32 - first as i32) * numerator as i32 / denominator as i32)
as i16
}
#[inline]

View file

@ -1,4 +1,3 @@
use conversions::Sample;
use cpal;
@ -7,7 +6,8 @@ use std::mem;
/// Iterator that converts from a certain sample rate to another.
#[derive(Clone, Debug)]
pub struct SampleRateConverter<I>
where I: Iterator
where
I: Iterator,
{
/// The iterator that gives us samples.
input: I,
@ -29,8 +29,9 @@ pub struct SampleRateConverter<I>
}
impl<I> SampleRateConverter<I>
where I: Iterator,
I::Item: Sample
where
I: Iterator,
I::Item: Sample,
{
///
///
@ -39,9 +40,10 @@ impl<I> SampleRateConverter<I>
/// Panicks if `from` or `to` are equal to 0.
///
#[inline]
pub fn new(mut input: I, from: cpal::SampleRate, to: cpal::SampleRate,
num_channels: cpal::ChannelCount)
-> SampleRateConverter<I> {
pub fn new(
mut input: I, from: cpal::SampleRate, to: cpal::SampleRate,
num_channels: cpal::ChannelCount,
) -> SampleRateConverter<I> {
let from = from.0;
let to = to.0;
@ -52,7 +54,11 @@ impl<I> SampleRateConverter<I>
let gcd = {
#[inline]
fn gcd(a: u32, b: u32) -> u32 {
if b == 0 { a } else { gcd(b, a % b) }
if b == 0 {
a
} else {
gcd(b, a % b)
}
}
gcd(from, to)
@ -108,8 +114,9 @@ impl<I> SampleRateConverter<I>
}
impl<I> Iterator for SampleRateConverter<I>
where I: Iterator,
I::Item: Sample + Clone
where
I: Iterator,
I::Item: Sample + Clone,
{
type Item = I::Item;
@ -137,11 +144,10 @@ impl<I> Iterator for SampleRateConverter<I>
self.next_input_frame();
}
self.current_frame_pos_in_chunk = 0;
} else {
// Finding the position of the first sample of the linear interpolation.
let req_left_sample = (self.from * self.next_output_frame_pos_in_chunk / self.to) %
self.from;
let req_left_sample =
(self.from * self.next_output_frame_pos_in_chunk / self.to) % self.from;
// Advancing `self.current_frame`, `self.next_frame` and
// `self.current_frame_pos_in_chunk` until the latter variable
@ -157,11 +163,10 @@ impl<I> Iterator for SampleRateConverter<I>
// `self.next_frame`.
let mut result = None;
let numerator = (self.from * self.next_output_frame_pos_in_chunk) % self.to;
for (off, (cur, next)) in
self.current_frame
.iter()
.zip(self.next_frame.iter())
.enumerate()
for (off, (cur, next)) in self.current_frame
.iter()
.zip(self.next_frame.iter())
.enumerate()
{
let sample = Sample::lerp(cur.clone(), next.clone(), numerator, self.to);
@ -175,7 +180,6 @@ impl<I> Iterator for SampleRateConverter<I>
// Incrementing the counter for the next iteration.
self.next_output_frame_pos_in_chunk += 1;
if result.is_some() {
result
} else {
@ -206,19 +210,19 @@ impl<I> Iterator for SampleRateConverter<I>
samples_after_chunk
};
// removing the samples of the current chunk that have not yet been read
let samples_after_chunk = samples_after_chunk
.saturating_sub(self.from
.saturating_sub(self.current_frame_pos_in_chunk + 2) as
usize *
self.current_frame.capacity());
let samples_after_chunk = samples_after_chunk.saturating_sub(
self.from
.saturating_sub(self.current_frame_pos_in_chunk + 2) as usize
* self.current_frame.capacity(),
);
// calculating the number of samples after the transformation
// TODO: this is wrong here \|/
let samples_after_chunk = samples_after_chunk * self.to as usize / self.from as usize;
// `samples_current_chunk` will contain the number of samples remaining to be output
// for the chunk currently being processed
let samples_current_chunk = (self.to - self.next_output_frame_pos_in_chunk) as usize *
self.current_frame.capacity();
let samples_current_chunk = (self.to - self.next_output_frame_pos_in_chunk) as usize
* self.current_frame.capacity();
samples_current_chunk + samples_after_chunk + self.output_buffer.len()
};
@ -233,8 +237,9 @@ impl<I> Iterator for SampleRateConverter<I>
}
impl<I> ExactSizeIterator for SampleRateConverter<I>
where I: ExactSizeIterator,
I::Item: Sample + Clone
where
I: ExactSizeIterator,
I::Item: Sample + Clone,
{
}

View file

@ -1,4 +1,3 @@
use std::io::{Read, Seek, SeekFrom};
use std::mem;
use std::time::Duration;
@ -9,7 +8,8 @@ use claxon::FlacReader;
/// Decoder for the Flac format.
pub struct FlacDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
reader: FlacReader<R>,
current_block: Vec<i32>,
@ -21,7 +21,8 @@ pub struct FlacDecoder<R>
}
impl<R> FlacDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
/// Attempts to decode the data as Flac.
pub fn new(mut data: R) -> Result<FlacDecoder<R>, R> {
@ -33,20 +34,22 @@ impl<R> FlacDecoder<R>
let spec = reader.streaminfo();
Ok(FlacDecoder {
reader: reader,
current_block: Vec::with_capacity(spec.max_block_size as usize *
spec.channels as usize),
current_block_channel_len: 1,
current_block_off: 0,
bits_per_sample: spec.bits_per_sample,
sample_rate: spec.sample_rate,
channels: spec.channels as u16,
})
reader: reader,
current_block: Vec::with_capacity(
spec.max_block_size as usize * spec.channels as usize,
),
current_block_channel_len: 1,
current_block_off: 0,
bits_per_sample: spec.bits_per_sample,
sample_rate: spec.sample_rate,
channels: spec.channels as u16,
})
}
}
impl<R> Source for FlacDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
@ -70,7 +73,8 @@ impl<R> Source for FlacDecoder<R>
}
impl<R> Iterator for FlacDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
type Item = i16;
@ -79,9 +83,9 @@ impl<R> Iterator for FlacDecoder<R>
loop {
if self.current_block_off < self.current_block.len() {
// Read from current block.
let real_offset = (self.current_block_off % self.channels as usize) *
self.current_block_channel_len +
self.current_block_off / self.channels as usize;
let real_offset = (self.current_block_off % self.channels as usize)
* self.current_block_channel_len
+ 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 {
@ -110,7 +114,8 @@ impl<R> Iterator for FlacDecoder<R>
/// Returns true if the stream contains Flac data, then resets it to where it was.
fn is_flac<R>(mut data: R) -> bool
where R: Read + Seek
where
R: Read + Seek,
{
let stream_pos = data.seek(SeekFrom::Current(0)).unwrap();

View file

@ -18,14 +18,17 @@ mod wav;
///
/// Supports WAV, Vorbis and Flac.
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
pub struct Decoder<R>(DecoderImpl<R>) where R: Read + Seek;
pub struct Decoder<R>(DecoderImpl<R>)
where
R: Read + Seek;
#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis")))]
pub struct Decoder<R>(::std::marker::PhantomData<R>);
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
enum DecoderImpl<R>
where R: Read + Seek
where
R: Read + Seek,
{
#[cfg(feature = "wav")]
Wav(wav::WavDecoder<R>),
@ -36,7 +39,8 @@ enum DecoderImpl<R>
}
impl<R> Decoder<R>
where R: Read + Seek + Send + 'static
where
R: Read + Seek + Send + 'static,
{
/// Builds a new decoder.
///
@ -73,16 +77,20 @@ impl<R> Decoder<R>
#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis")))]
impl<R> Iterator for Decoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
type Item = i16;
fn next(&mut self) -> Option<i16> { None }
fn next(&mut self) -> Option<i16> {
None
}
}
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
impl<R> Iterator for Decoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
type Item = i16;
@ -113,17 +121,27 @@ impl<R> Iterator for Decoder<R>
#[cfg(not(any(feature = "wav", feature = "flac", feature = "vorbis")))]
impl<R> Source for Decoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
fn current_frame_len(&self) -> Option<usize> { Some(0) }
fn channels(&self) -> u16 { 0 }
fn sample_rate(&self) -> u32 { 1 }
fn total_duration(&self) -> Option<Duration> { Some(Duration::default()) }
fn current_frame_len(&self) -> Option<usize> {
Some(0)
}
fn channels(&self) -> u16 {
0
}
fn sample_rate(&self) -> u32 {
1
}
fn total_duration(&self) -> Option<Duration> {
Some(Duration::default())
}
}
#[cfg(any(feature = "wav", feature = "flac", feature = "vorbis"))]
impl<R> Source for Decoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -8,14 +8,16 @@ use lewton::inside_ogg::OggStreamReader;
/// Decoder for an OGG file that contains Vorbis sound format.
pub struct VorbisDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
stream_reader: OggStreamReader<R>,
current_data: vec::IntoIter<i16>,
}
impl<R> VorbisDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
/// Attempts to decode the data as ogg/vorbis.
pub fn new(data: R) -> Result<VorbisDecoder<R>, ()> {
@ -37,14 +39,15 @@ impl<R> VorbisDecoder<R>
};
Ok(VorbisDecoder {
stream_reader: stream_reader,
current_data: data.into_iter(),
})
stream_reader: stream_reader,
current_data: data.into_iter(),
})
}
}
impl<R> Source for VorbisDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
@ -68,7 +71,8 @@ impl<R> Source for VorbisDecoder<R>
}
impl<R> Iterator for VorbisDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
type Item = i16;

View file

@ -7,7 +7,8 @@ use hound::WavReader;
/// Decoder for the WAV format.
pub struct WavDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
reader: SamplesIterator<R>,
sample_rate: u32,
@ -15,7 +16,8 @@ pub struct WavDecoder<R>
}
impl<R> WavDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
/// Attempts to decode the data as WAV.
pub fn new(mut data: R) -> Result<WavDecoder<R>, R> {
@ -31,22 +33,24 @@ impl<R> WavDecoder<R>
};
Ok(WavDecoder {
reader: reader,
sample_rate: spec.sample_rate,
channels: spec.channels,
})
reader: reader,
sample_rate: spec.sample_rate,
channels: spec.channels,
})
}
}
struct SamplesIterator<R>
where R: Read + Seek
where
R: Read + Seek,
{
reader: WavReader<R>,
samples_read: u32,
}
impl<R> Iterator for SamplesIterator<R>
where R: Read + Seek
where
R: Read + Seek,
{
type Item = i16;
@ -68,12 +72,14 @@ impl<R> Iterator for SamplesIterator<R>
}
impl<R> ExactSizeIterator for SamplesIterator<R>
where R: Read + Seek
where
R: Read + Seek,
{
}
impl<R> Source for WavDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
@ -98,7 +104,8 @@ impl<R> Source for WavDecoder<R>
}
impl<R> Iterator for WavDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
type Item = i16;
@ -114,13 +121,15 @@ impl<R> Iterator for WavDecoder<R>
}
impl<R> ExactSizeIterator for WavDecoder<R>
where R: Read + Seek
where
R: Read + Seek,
{
}
/// Returns true if the stream contains WAV data, then resets it to where it was.
fn is_wave<R>(mut data: R) -> bool
where R: Read + Seek
where
R: Read + Seek,
{
let stream_pos = data.seek(SeekFrom::Current(0)).unwrap();

View file

@ -1,9 +1,9 @@
//! Queue that plays sounds one after the other.
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::sync::Mutex;
use std::time::Duration;
use source::Source;
@ -17,16 +17,18 @@ use Sample;
/// added to the mixer will be converted to these values.
///
/// After creating a mixer, you can add new sounds with the controller.
pub fn mixer<S>(channels: u16, sample_rate: u32)
-> (Arc<DynamicMixerController<S>>, DynamicMixer<S>)
where S: Sample + Send + 'static
pub fn mixer<S>(
channels: u16, sample_rate: u32,
) -> (Arc<DynamicMixerController<S>>, DynamicMixer<S>)
where
S: Sample + Send + 'static,
{
let input = Arc::new(DynamicMixerController {
has_pending: AtomicBool::new(false),
pending_sources: Mutex::new(Vec::new()),
channels: channels,
sample_rate: sample_rate,
});
has_pending: AtomicBool::new(false),
pending_sources: Mutex::new(Vec::new()),
channels: channels,
sample_rate: sample_rate,
});
let output = DynamicMixer {
current_sources: Vec::with_capacity(16),
@ -45,12 +47,14 @@ pub struct DynamicMixerController<S> {
}
impl<S> DynamicMixerController<S>
where S: Sample + Send + 'static
where
S: Sample + Send + 'static,
{
/// Adds a new source to mix to the existing ones.
#[inline]
pub fn add<T>(&self, source: T)
where T: Source<Item = S> + Send + 'static
where
T: Source<Item = S> + Send + 'static,
{
let uniform_source = UniformSourceIterator::new(source, self.channels, self.sample_rate);
self.pending_sources
@ -71,7 +75,8 @@ pub struct DynamicMixer<S> {
}
impl<S> Source for DynamicMixer<S>
where S: Sample + Send + 'static
where
S: Sample + Send + 'static,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
@ -95,7 +100,8 @@ impl<S> Source for DynamicMixer<S>
}
impl<S> Iterator for DynamicMixer<S>
where S: Sample + Send + 'static
where
S: Sample + Send + 'static,
{
type Item = S;

View file

@ -1,5 +1,5 @@
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::Weak;
@ -8,9 +8,9 @@ use std::thread::Builder;
use cpal::Device;
use cpal::EventLoop;
use cpal::Sample as CpalSample;
use cpal::UnknownTypeOutputBuffer;
use cpal::StreamId;
use cpal::StreamData;
use cpal::StreamId;
use cpal::UnknownTypeOutputBuffer;
use dynamic_mixer;
use source::Source;
@ -18,7 +18,8 @@ use source::Source;
///
/// The playing uses a background thread.
pub fn play_raw<S>(device: &Device, source: S)
where S: Source<Item = f32> + Send + 'static
where
S: Source<Item = f32> + Send + 'static,
{
lazy_static! {
static ref ENGINE: Arc<Engine> = {
@ -72,30 +73,34 @@ fn audio_callback(engine: &Arc<Engine>, stream_id: StreamId, buffer: StreamData)
};
match buffer {
StreamData::Output { buffer: UnknownTypeOutputBuffer::U16(mut buffer) } => {
for d in buffer.iter_mut() {
*d = mixer_rx.next().map(|s| s.to_u16()).unwrap_or(u16::max_value() / 2);
}
StreamData::Output {
buffer: UnknownTypeOutputBuffer::U16(mut buffer),
} => for d in buffer.iter_mut() {
*d = mixer_rx
.next()
.map(|s| s.to_u16())
.unwrap_or(u16::max_value() / 2);
},
StreamData::Output { buffer: UnknownTypeOutputBuffer::I16(mut buffer) } => {
for d in buffer.iter_mut() {
*d = mixer_rx.next().map(|s| s.to_i16()).unwrap_or(0i16);
}
StreamData::Output {
buffer: UnknownTypeOutputBuffer::I16(mut buffer),
} => for d in buffer.iter_mut() {
*d = mixer_rx.next().map(|s| s.to_i16()).unwrap_or(0i16);
},
StreamData::Output { buffer: UnknownTypeOutputBuffer::F32(mut buffer) } => {
for d in buffer.iter_mut() {
*d = mixer_rx.next().unwrap_or(0f32);
}
StreamData::Output {
buffer: UnknownTypeOutputBuffer::F32(mut buffer),
} => for d in buffer.iter_mut() {
*d = mixer_rx.next().unwrap_or(0f32);
},
StreamData::Input { buffer: _ } => {
panic!("Can't play an input stream!");
}
},
};
}
// Builds a new sink that targets a given device.
fn start<S>(engine: &Arc<Engine>, device: &Device, source: S)
where S: Source<Item = f32> + Send + 'static
where
S: Source<Item = f32> + Send + 'static,
{
let mut stream_to_start = None;
@ -131,17 +136,26 @@ fn start<S>(engine: &Arc<Engine>, device: &Device, source: S)
// Adds a new stream to the engine.
// TODO: handle possible errors here
fn new_output_stream(engine: &Arc<Engine>, device: &Device) -> (Arc<dynamic_mixer::DynamicMixerController<f32>>, StreamId) {
fn new_output_stream(
engine: &Arc<Engine>, device: &Device,
) -> (Arc<dynamic_mixer::DynamicMixerController<f32>>, StreamId) {
// Determine the format to use for the new stream.
let format = device.default_output_format()
.expect("The device doesn't support any format!?");
let format = device
.default_output_format()
.expect("The device doesn't support any format!?");
let stream_id = engine.events_loop.build_output_stream(device, &format).unwrap();
let (mixer_tx, mixer_rx) = {
dynamic_mixer::mixer::<f32>(format.channels, format.sample_rate.0)
};
let stream_id = engine
.events_loop
.build_output_stream(device, &format)
.unwrap();
let (mixer_tx, mixer_rx) =
{ dynamic_mixer::mixer::<f32>(format.channels, format.sample_rate.0) };
engine.dynamic_mixers.lock().unwrap().insert(stream_id.clone(), mixer_rx);
engine
.dynamic_mixers
.lock()
.unwrap()
.insert(stream_id.clone(), mixer_rx);
(mixer_tx, stream_id)
}

View file

@ -83,6 +83,7 @@
#![cfg_attr(test, deny(missing_docs))]
extern crate cgmath;
#[cfg(feature = "flac")]
extern crate claxon;
extern crate cpal;
@ -92,9 +93,9 @@ extern crate hound;
extern crate lazy_static;
#[cfg(feature = "vorbis")]
extern crate lewton;
extern crate cgmath;
pub use cpal::{Device, default_output_device, default_input_device, devices, output_devices, input_devices};
pub use cpal::{default_input_device, default_output_device, devices, input_devices,
output_devices, Device};
pub use conversions::Sample;
pub use decoder::Decoder;
@ -119,7 +120,8 @@ pub mod source;
/// Plays a sound once. Returns a `Sink` that can be used to control the sound.
#[inline]
pub fn play_once<R>(device: &Device, input: R) -> Result<Sink, decoder::DecoderError>
where R: Read + Seek + Send + 'static
where
R: Read + Seek + Send + 'static,
{
let input = decoder::Decoder::new(input)?;
let sink = Sink::new(device);

View file

@ -1,12 +1,12 @@
//! Queue that plays sounds one after the other.
use std::sync::Arc;
use std::sync::Mutex;
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::time::Duration;
use source::Empty;
@ -27,12 +27,13 @@ use Sample;
/// - If you pass `false`, then the queue will report that it has finished playing.
///
pub fn queue<S>(keep_alive_if_empty: bool) -> (Arc<SourcesQueueInput<S>>, SourcesQueueOutput<S>)
where S: Sample + Send + 'static
where
S: Sample + Send + 'static,
{
let input = Arc::new(SourcesQueueInput {
next_sounds: Mutex::new(Vec::new()),
keep_alive_if_empty: AtomicBool::new(keep_alive_if_empty),
});
next_sounds: Mutex::new(Vec::new()),
keep_alive_if_empty: AtomicBool::new(keep_alive_if_empty),
});
let output = SourcesQueueOutput {
current: Box::new(Empty::<S>::new()) as Box<_>,
@ -54,12 +55,14 @@ pub struct SourcesQueueInput<S> {
}
impl<S> SourcesQueueInput<S>
where S: Sample + Send + 'static
where
S: Sample + Send + 'static,
{
/// Adds a new source to the end of the queue.
#[inline]
pub fn append<T>(&self, source: T)
where T: Source<Item = S> + Send + 'static
where
T: Source<Item = S> + Send + 'static,
{
self.next_sounds
.lock()
@ -72,7 +75,8 @@ impl<S> SourcesQueueInput<S>
/// The `Receiver` will be signalled when the sound has finished playing.
#[inline]
pub fn append_with_signal<T>(&self, source: T) -> Receiver<()>
where T: Source<Item = S> + Send + 'static
where
T: Source<Item = S> + Send + 'static,
{
let (tx, rx) = mpsc::channel();
self.next_sounds
@ -104,7 +108,8 @@ pub struct SourcesQueueOutput<S> {
}
impl<S> Source for SourcesQueueOutput<S>
where S: Sample + Send + 'static
where
S: Sample + Send + 'static,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
@ -155,7 +160,8 @@ impl<S> Source for SourcesQueueOutput<S>
}
impl<S> Iterator for SourcesQueueOutput<S>
where S: Sample + Send + 'static
where
S: Sample + Send + 'static,
{
type Item = S;
@ -182,7 +188,8 @@ impl<S> Iterator for SourcesQueueOutput<S>
}
impl<S> SourcesQueueOutput<S>
where S: Sample + Send + 'static
where
S: Sample + Send + 'static,
{
// Called when `current` is empty and we must jump to the next element.
// Returns `Ok` if the sound should continue playing, or an error if it should stop.
@ -200,7 +207,10 @@ impl<S> SourcesQueueOutput<S>
if self.input.keep_alive_if_empty.load(Ordering::Acquire) {
// Play a short silence in order to avoid spinlocking.
let silence = Zero::<S>::new(1, 44000); // TODO: meh
(Box::new(silence.take_duration(Duration::from_millis(10))) as Box<_>, None)
(
Box::new(silence.take_duration(Duration::from_millis(10))) as Box<_>,
None,
)
} else {
return Err(());
}

View file

@ -1,17 +1,16 @@
use std::sync::atomic::Ordering;
use std::sync::atomic::{AtomicBool, AtomicUsize};
use std::sync::mpsc::Receiver;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::atomic::{AtomicBool, AtomicUsize};
use std::sync::atomic::Ordering;
use std::sync::mpsc::Receiver;
use std::time::Duration;
use play_raw;
use queue;
use source::Done;
use Device;
use Sample;
use Source;
use source::Done;
use play_raw;
use queue;
/// Handle to an device that outputs sounds.
///
@ -56,9 +55,10 @@ impl Sink {
/// Appends a sound to the queue of sounds to play.
#[inline]
pub fn append<S>(&self, source: S)
where S: Source + Send + 'static,
S::Item: Sample,
S::Item: Send
where
S: Source + Send + 'static,
S::Item: Sample,
S::Item: Send,
{
let controls = self.controls.clone();

View file

@ -5,8 +5,9 @@ use Source;
/// Internal function that builds a `Amplify` object.
pub fn amplify<I>(input: I, factor: f32) -> Amplify<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
Amplify {
input: input,
@ -48,8 +49,9 @@ impl<I> Amplify<I> {
}
impl<I> Iterator for Amplify<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
type Item = I::Item;
@ -65,14 +67,16 @@ impl<I> Iterator for Amplify<I>
}
impl<I> ExactSizeIterator for Amplify<I>
where I: Source + ExactSizeIterator,
I::Item: Sample
where
I: Source + ExactSizeIterator,
I::Item: Sample,
{
}
impl<I> Source for Amplify<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -7,7 +7,8 @@ use Source;
/// Internal function that builds a `BltFilter` object.
pub fn low_pass<I>(input: I, freq: u32) -> BltFilter<I>
where I: Source<Item = f32>
where
I: Source<Item = f32>,
{
BltFilter {
input: input,
@ -58,7 +59,8 @@ impl<I> BltFilter<I> {
}
impl<I> Iterator for BltFilter<I>
where I: Source<Item = f32>
where
I: Source<Item = f32>,
{
type Item = f32;
@ -99,12 +101,14 @@ impl<I> Iterator for BltFilter<I>
}
impl<I> ExactSizeIterator for BltFilter<I>
where I: Source<Item = f32> + ExactSizeIterator
where
I: Source<Item = f32> + ExactSizeIterator,
{
}
impl<I> Source for BltFilter<I>
where I: Source<Item = f32>
where
I: Source<Item = f32>,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -8,8 +8,9 @@ use Source;
/// Internal function that builds a `Buffered` object.
#[inline]
pub fn buffered<I>(input: I) -> Buffered<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
let total_duration = input.total_duration();
let first_frame = extract(input);
@ -23,8 +24,9 @@ pub fn buffered<I>(input: I) -> Buffered<I>
/// Iterator that at the same time extracts data from the iterator and stores it in a buffer.
pub struct Buffered<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
/// Immutable reference to the next frame of data. Cannot be `Frame::Input`.
current_frame: Arc<Frame<I>>,
@ -37,8 +39,9 @@ pub struct Buffered<I>
}
enum Frame<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
/// Data that has already been extracted from the iterator. Also contains a pointer to the
/// next frame.
@ -53,8 +56,9 @@ enum Frame<I>
}
struct FrameData<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
data: Vec<I::Item>,
channels: u16,
@ -64,8 +68,9 @@ struct FrameData<I>
/// Builds a frame from the input iterator.
fn extract<I>(mut input: I) -> Arc<Frame<I>>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
let frame_len = input.current_frame_len();
@ -75,7 +80,7 @@ fn extract<I>(mut input: I) -> Arc<Frame<I>>
let channels = input.channels();
let rate = input.sample_rate();
let data : Vec<I::Item> = input
let data: Vec<I::Item> = input
.by_ref()
.take(cmp::min(frame_len.unwrap_or(32768), 32768))
.collect();
@ -85,16 +90,17 @@ fn extract<I>(mut input: I) -> Arc<Frame<I>>
}
Arc::new(Frame::Data(FrameData {
data: data,
channels: channels,
rate: rate,
next: Mutex::new(Arc::new(Frame::Input(Mutex::new(Some(input))))),
}))
data: data,
channels: channels,
rate: rate,
next: Mutex::new(Arc::new(Frame::Input(Mutex::new(Some(input))))),
}))
}
impl<I> Buffered<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
/// Advances to the next frame.
fn next_frame(&mut self) {
@ -123,8 +129,9 @@ impl<I> Buffered<I>
}
impl<I> Iterator for Buffered<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
type Item = I::Item;
@ -148,7 +155,6 @@ impl<I> Iterator for Buffered<I>
&Frame::Input(_) => unreachable!(),
};
if advance_frame {
self.next_frame();
}
@ -168,8 +174,9 @@ impl<I> Iterator for Buffered<I>
}*/
impl<I> Source for Buffered<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
@ -205,8 +212,9 @@ impl<I> Source for Buffered<I>
}
impl<I> Clone for Buffered<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
#[inline]
fn clone(&self) -> Buffered<I> {

View file

@ -1,13 +1,14 @@
use std::time::Duration;
use Sample;
use Source;
use std::time::Duration;
/// 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)]
pub struct ChannelVolume<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
input: I,
// Channel number is used as index for amplification value.
@ -18,12 +19,14 @@ pub struct ChannelVolume<I>
}
impl<I> ChannelVolume<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
pub fn new(mut input: I, channel_volumes: Vec<f32>) -> ChannelVolume<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
let mut sample = I::Item::zero_value();
for _ in 0 .. input.channels() {
@ -47,8 +50,9 @@ impl<I> ChannelVolume<I>
}
impl<I> Iterator for ChannelVolume<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
type Item = I::Item;
@ -80,14 +84,16 @@ impl<I> Iterator for ChannelVolume<I>
}
impl<I> ExactSizeIterator for ChannelVolume<I>
where I: Source + ExactSizeIterator,
I::Item: Sample
where
I: Source + ExactSizeIterator,
I::Item: Sample,
{
}
impl<I> Source for ChannelVolume<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -5,8 +5,9 @@ use Source;
/// Internal function that builds a `Delay` object.
pub fn delay<I>(input: I, duration: Duration) -> Delay<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
let duration_ns = duration.as_secs() * 1000000000 + duration.subsec_nanos() as u64;
let samples = duration_ns * input.sample_rate() as u64 * input.channels() as u64 / 1000000000;
@ -21,8 +22,9 @@ pub fn delay<I>(input: I, duration: Duration) -> Delay<I>
/// A source that delays the given source by a certain amount.
#[derive(Clone, Debug)]
pub struct Delay<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
input: I,
remaining_samples: usize,
@ -30,8 +32,9 @@ pub struct Delay<I>
}
impl<I> Iterator for Delay<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
type Item = <I as Iterator>::Item;
@ -40,7 +43,6 @@ impl<I> Iterator for Delay<I>
if self.remaining_samples >= 1 {
self.remaining_samples -= 1;
Some(Sample::zero_value())
} else {
self.input.next()
}
@ -49,13 +51,17 @@ impl<I> Iterator for Delay<I>
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (min, max) = self.input.size_hint();
(min + self.remaining_samples, max.map(|v| v + self.remaining_samples))
(
min + self.remaining_samples,
max.map(|v| v + self.remaining_samples),
)
}
}
impl<I> Source for Delay<I>
where I: Iterator + Source,
I::Item: Sample
where
I: Iterator + Source,
I::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -1,14 +1,15 @@
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::time::Duration;
use Sample;
use Source;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Duration;
/// WHen the inner source is empty this decrements an AtomicUsize
#[derive(Debug, Clone)]
pub struct Done<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
input: I,
signal: Arc<AtomicUsize>,
@ -16,18 +17,24 @@ pub struct Done<I>
}
impl<I> Done<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
#[inline]
pub fn new(input: I, signal: Arc<AtomicUsize>) -> Done<I> {
Done { input, signal, signal_sent: false }
Done {
input,
signal,
signal_sent: false,
}
}
}
impl<I: Source> Iterator for Done<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
type Item = I::Item;
@ -43,8 +50,9 @@ impl<I: Source> Iterator for Done<I>
}
impl<I> Source for Done<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -1,8 +1,7 @@
use Sample;
use Source;
use std::marker::PhantomData;
use std::time::Duration;
use Sample;
use Source;
/// An empty source.
#[derive(Debug, Copy, Clone)]
@ -25,7 +24,8 @@ impl<S> Iterator for Empty<S> {
}
impl<S> Source for Empty<S>
where S: Sample
where
S: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -5,8 +5,9 @@ use Source;
/// Internal function that builds a `FadeIn` object.
pub fn fadein<I>(input: I, duration: Duration) -> FadeIn<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
let duration = duration.as_secs() * 1000000000 + duration.subsec_nanos() as u64;
@ -20,8 +21,9 @@ pub fn fadein<I>(input: I, duration: Duration) -> FadeIn<I>
/// Filter that modifies each sample by a given value.
#[derive(Clone, Debug)]
pub struct FadeIn<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
input: I,
remaining_ns: f32,
@ -29,8 +31,9 @@ pub struct FadeIn<I>
}
impl<I> Iterator for FadeIn<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
type Item = I::Item;
@ -41,8 +44,8 @@ impl<I> Iterator for FadeIn<I>
}
let factor = 1.0 - self.remaining_ns / self.total_ns;
self.remaining_ns -= 1000000000.0 /
(self.input.sample_rate() as f32 * self.channels() as f32);
self.remaining_ns -=
1000000000.0 / (self.input.sample_rate() as f32 * self.channels() as f32);
self.input.next().map(|value| value.amplify(factor))
}
@ -53,14 +56,16 @@ impl<I> Iterator for FadeIn<I>
}
impl<I> ExactSizeIterator for FadeIn<I>
where I: Source + ExactSizeIterator,
I::Item: Sample
where
I: Source + ExactSizeIterator,
I::Item: Sample,
{
}
impl<I> Source for FadeIn<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -1,6 +1,5 @@
use source::FromIter;
use source::from_iter;
use source::FromIter;
/// Builds a source that chains sources built from a factory.
///
@ -10,7 +9,8 @@ use source::from_iter;
///
/// If the `factory` closure returns `None`, then the sound ends.
pub fn from_factory<F, S>(factory: F) -> FromIter<FromFactoryIter<F>>
where F: FnMut() -> Option<S>
where
F: FnMut() -> Option<S>,
{
from_iter(FromFactoryIter { factory: factory })
}
@ -21,7 +21,8 @@ pub struct FromFactoryIter<F> {
}
impl<F, S> Iterator for FromFactoryIter<F>
where F: FnMut() -> Option<S>
where
F: FnMut() -> Option<S>,
{
type Item = S;

View file

@ -11,7 +11,8 @@ use Source;
///
/// If the `iterator` produces `None`, then the sound ends.
pub fn from_iter<I>(iterator: I) -> FromIter<I::IntoIter>
where I: IntoIterator
where
I: IntoIterator,
{
let mut iterator = iterator.into_iter();
let first_source = iterator.next();
@ -25,7 +26,8 @@ pub fn from_iter<I>(iterator: I) -> FromIter<I::IntoIter>
/// A source that chains sources provided by an iterator.
#[derive(Clone)]
pub struct FromIter<I>
where I: Iterator
where
I: Iterator,
{
// The iterator that provides sources.
iterator: I,
@ -34,9 +36,10 @@ pub struct FromIter<I>
}
impl<I> Iterator for FromIter<I>
where I: Iterator,
I::Item: Iterator + Source,
<I::Item as Iterator>::Item: Sample
where
I: Iterator,
I::Item: Iterator + Source,
<I::Item as Iterator>::Item: Sample,
{
type Item = <I::Item as Iterator>::Item;
@ -68,9 +71,10 @@ impl<I> Iterator for FromIter<I>
}
impl<I> Source for FromIter<I>
where I: Iterator,
I::Item: Iterator + Source,
<I::Item as Iterator>::Item: Sample
where
I: Iterator,
I::Item: Iterator + Source,
<I::Item as Iterator>::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
@ -137,19 +141,20 @@ impl<I> Source for FromIter<I>
#[cfg(test)]
mod tests {
use buffer::SamplesBuffer;
use source::Source;
use source::from_iter;
use source::Source;
#[test]
fn basic() {
let mut rx =
from_iter((0 .. 2).map(|n| if n == 0 {
SamplesBuffer::new(1, 48000, vec![10i16, -10, 10, -10])
} else if n == 1 {
SamplesBuffer::new(2, 96000, vec![5i16, 5, 5, 5])
} else {
unreachable!()
}));
let mut rx = from_iter((0 .. 2).map(|n| {
if n == 0 {
SamplesBuffer::new(1, 48000, vec![10i16, -10, 10, -10])
} else if n == 1 {
SamplesBuffer::new(2, 96000, vec![5i16, 5, 5, 5])
} else {
unreachable!()
}
}));
assert_eq!(rx.channels(), 1);
assert_eq!(rx.sample_rate(), 48000);

View file

@ -8,10 +8,11 @@ use Source;
/// Internal function that builds a `Mix` object.
pub fn mix<I1, I2>(input1: I1, input2: I2) -> Mix<I1, I2>
where I1: Source,
I1::Item: Sample,
I2: Source,
I2::Item: Sample
where
I1: Source,
I1::Item: Sample,
I2: Source,
I2::Item: Sample,
{
let channels = input1.channels();
let rate = input1.sample_rate();
@ -25,20 +26,22 @@ pub fn mix<I1, I2>(input1: I1, input2: I2) -> Mix<I1, I2>
/// Filter that modifies each sample by a given value.
#[derive(Clone)]
pub struct Mix<I1, I2>
where I1: Source,
I1::Item: Sample,
I2: Source,
I2::Item: Sample
where
I1: Source,
I1::Item: Sample,
I2: Source,
I2::Item: Sample,
{
input1: UniformSourceIterator<I1, I1::Item>,
input2: UniformSourceIterator<I2, I1::Item>,
}
impl<I1, I2> Iterator for Mix<I1, I2>
where I1: Source,
I1::Item: Sample,
I2: Source,
I2::Item: Sample
where
I1: Source,
I1::Item: Sample,
I2: Source,
I2::Item: Sample,
{
type Item = I1::Item;
@ -71,18 +74,20 @@ impl<I1, I2> Iterator for Mix<I1, I2>
}
impl<I1, I2> ExactSizeIterator for Mix<I1, I2>
where I1: Source + ExactSizeIterator,
I1::Item: Sample,
I2: Source + ExactSizeIterator,
I2::Item: Sample
where
I1: Source + ExactSizeIterator,
I1::Item: Sample,
I2: Source + ExactSizeIterator,
I2::Item: Sample,
{
}
impl<I1, I2> Source for Mix<I1, I2>
where I1: Source,
I1::Item: Sample,
I2: Source,
I2::Item: Sample
where
I1: Source,
I1::Item: Sample,
I2: Source,
I2::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -12,8 +12,8 @@ pub use self::delay::Delay;
pub use self::done::Done;
pub use self::empty::Empty;
pub use self::fadein::FadeIn;
pub use self::from_factory::{FromFactoryIter, from_factory};
pub use self::from_iter::{FromIter, from_iter};
pub use self::from_factory::{from_factory, FromFactoryIter};
pub use self::from_iter::{from_iter, FromIter};
pub use self::mix::Mix;
pub use self::pausable::Pausable;
pub use self::periodic::PeriodicAccess;
@ -30,6 +30,7 @@ pub use self::zero::Zero;
mod amplify;
mod blt;
mod buffered;
mod channel_volume;
mod delay;
mod done;
mod empty;
@ -42,7 +43,6 @@ mod periodic;
mod repeat;
mod samples_converter;
mod sine;
mod channel_volume;
mod spatial;
mod speed;
mod stoppable;
@ -118,7 +118,8 @@ mod zero;
/// channels can potentially change.
///
pub trait Source: Iterator
where Self::Item: Sample
where
Self::Item: Sample,
{
/// Returns the number of samples before the current frame ends. `None` means "infinite" or
/// "until the sound ends".
@ -142,7 +143,8 @@ pub trait Source: Iterator
/// Stores the source in a buffer in addition to returning it. This iterator can be cloned.
#[inline]
fn buffered(self) -> Buffered<Self>
where Self: Sized
where
Self: Sized,
{
buffered::buffered(self)
}
@ -150,9 +152,10 @@ pub trait Source: Iterator
/// Mixes this source with another one.
#[inline]
fn mix<S>(self, other: S) -> Mix<Self, S>
where Self: Sized,
S: Source,
S::Item: Sample
where
Self: Sized,
S: Source,
S::Item: Sample,
{
mix::mix(self, other)
}
@ -163,7 +166,8 @@ pub trait Source: Iterator
/// proportional to the size of the sound.
#[inline]
fn repeat_infinite(self) -> Repeat<Self>
where Self: Sized
where
Self: Sized,
{
repeat::repeat(self)
}
@ -171,7 +175,8 @@ pub trait Source: Iterator
/// Takes a certain duration of this source and then stops.
#[inline]
fn take_duration(self, duration: Duration) -> TakeDuration<Self>
where Self: Sized
where
Self: Sized,
{
take::take_duration(self, duration)
}
@ -182,7 +187,8 @@ pub trait Source: Iterator
/// source.
#[inline]
fn delay(self, duration: Duration) -> Delay<Self>
where Self: Sized
where
Self: Sized,
{
delay::delay(self, duration)
}
@ -190,7 +196,8 @@ pub trait Source: Iterator
/// Amplifies the sound by the given value.
#[inline]
fn amplify(self, value: f32) -> Amplify<Self>
where Self: Sized
where
Self: Sized,
{
amplify::amplify(self, value)
}
@ -198,7 +205,8 @@ pub trait Source: Iterator
/// Fades in the sound.
#[inline]
fn fade_in(self, duration: Duration) -> FadeIn<Self>
where Self: Sized
where
Self: Sized,
{
fadein::fadein(self, duration)
}
@ -206,8 +214,9 @@ pub trait Source: Iterator
/// Calls the `access` closure on `Self` every time `period` elapsed.
#[inline]
fn periodic_access<F>(self, period: Duration, access: F) -> PeriodicAccess<Self, F>
where Self: Sized,
F: FnMut(&mut Self)
where
Self: Sized,
F: FnMut(&mut Self),
{
periodic::periodic(self, period, access)
}
@ -215,7 +224,8 @@ pub trait Source: Iterator
/// Changes the play speed of the sound. Does not adjust the samples, only the play speed.
#[inline]
fn speed(self, ratio: f32) -> Speed<Self>
where Self: Sized
where
Self: Sized,
{
speed::speed(self, ratio)
}
@ -234,7 +244,8 @@ pub trait Source: Iterator
/// ```
#[inline]
fn reverb(self, duration: Duration, amplitude: f32) -> Mix<Self, Delay<Amplify<Self>>>
where Self: Sized + Clone
where
Self: Sized + Clone,
{
let echo = self.clone().amplify(amplitude).delay(duration);
self.mix(echo)
@ -243,8 +254,9 @@ pub trait Source: Iterator
/// Converts the samples of this source to another type.
#[inline]
fn convert_samples<D>(self) -> SamplesConverter<Self, D>
where Self: Sized,
D: Sample
where
Self: Sized,
D: Sample,
{
SamplesConverter::new(self)
}
@ -253,7 +265,8 @@ pub trait Source: Iterator
// TODO: add example
#[inline]
fn pausable(self, initially_paused: bool) -> Pausable<Self>
where Self: Sized
where
Self: Sized,
{
pausable::pausable(self, initially_paused)
}
@ -262,7 +275,8 @@ pub trait Source: Iterator
// TODO: add example
#[inline]
fn stoppable(self) -> Stoppable<Self>
where Self: Sized
where
Self: Sized,
{
stoppable::stoppable(self)
}
@ -271,15 +285,17 @@ pub trait Source: Iterator
/// **Warning**: Probably buggy.
#[inline]
fn low_pass(self, freq: u32) -> BltFilter<Self>
where Self: Sized,
Self: Source<Item = f32>
where
Self: Sized,
Self: Source<Item = f32>,
{
blt::low_pass(self, freq)
}
}
impl<S> Source for Box<Source<Item = S>>
where S: Sample
where
S: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
@ -303,7 +319,8 @@ impl<S> Source for Box<Source<Item = S>>
}
impl<S> Source for Box<Source<Item = S> + Send>
where S: Sample
where
S: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
@ -327,7 +344,8 @@ impl<S> Source for Box<Source<Item = S> + Send>
}
impl<S> Source for Box<Source<Item = S> + Send + Sync>
where S: Sample
where
S: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -46,8 +46,9 @@ impl<I> Pausable<I> {
}
impl<I> Iterator for Pausable<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
type Item = I::Item;
@ -67,8 +68,9 @@ impl<I> Iterator for Pausable<I>
}
impl<I> Source for Pausable<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -5,8 +5,9 @@ use Source;
/// Internal function that builds a `PeriodicAccess` object.
pub fn periodic<I, F>(source: I, period: Duration, modifier: F) -> PeriodicAccess<I, F>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
// TODO: handle the fact that the samples rate can change
// TODO: generally, just wrong
@ -38,9 +39,10 @@ pub struct PeriodicAccess<I, F> {
}
impl<I, F> Iterator for PeriodicAccess<I, F>
where I: Source,
I::Item: Sample,
F: FnMut(&mut I)
where
I: Source,
I::Item: Sample,
F: FnMut(&mut I),
{
type Item = I::Item;
@ -62,9 +64,10 @@ impl<I, F> Iterator for PeriodicAccess<I, F>
}
impl<I, F> Source for PeriodicAccess<I, F>
where I: Source,
I::Item: Sample,
F: FnMut(&mut I)
where
I: Source,
I::Item: Sample,
F: FnMut(&mut I),
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -7,8 +7,9 @@ use Source;
/// Internal function that builds a `Repeat` object.
pub fn repeat<I>(input: I) -> Repeat<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
let input = input.buffered();
Repeat {
@ -20,16 +21,18 @@ pub fn repeat<I>(input: I) -> Repeat<I>
/// A source that repeats the given source.
#[derive(Clone)]
pub struct Repeat<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
inner: Buffered<I>,
next: Buffered<I>,
}
impl<I> Iterator for Repeat<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
type Item = <I as Iterator>::Item;
@ -51,8 +54,9 @@ impl<I> Iterator for Repeat<I>
}
impl<I> Source for Repeat<I>
where I: Iterator + Source,
I::Item: Sample
where
I: Iterator + Source,
I::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -12,18 +12,20 @@ use Source;
/// channels and samples rate have been passed to `new`.
#[derive(Clone)]
pub struct SamplesConverter<I, D>
where I: Source,
I::Item: Sample,
D: Sample
where
I: Source,
I::Item: Sample,
D: Sample,
{
inner: I,
dest: PhantomData<D>,
}
impl<I, D> SamplesConverter<I, D>
where I: Source,
I::Item: Sample,
D: Sample
where
I: Source,
I::Item: Sample,
D: Sample,
{
#[inline]
pub fn new(input: I) -> SamplesConverter<I, D> {
@ -35,9 +37,10 @@ impl<I, D> SamplesConverter<I, D>
}
impl<I, D> Iterator for SamplesConverter<I, D>
where I: Source,
I::Item: Sample,
D: Sample
where
I: Source,
I::Item: Sample,
D: Sample,
{
type Item = D;
@ -53,16 +56,18 @@ impl<I, D> Iterator for SamplesConverter<I, D>
}
impl<I, D> ExactSizeIterator for SamplesConverter<I, D>
where I: Source + ExactSizeIterator,
I::Item: Sample,
D: Sample
where
I: Source + ExactSizeIterator,
I::Item: Sample,
D: Sample,
{
}
impl<I, D> Source for SamplesConverter<I, D>
where I: Source,
I::Item: Sample,
D: Sample
where
I: Source,
I::Item: Sample,
D: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -1,6 +1,5 @@
use Source;
use std::time::Duration;
use Source;
/// An infinite source that produces a sine.
///

View file

@ -1,37 +1,44 @@
use Sample;
use Source;
use cgmath::{InnerSpace, Point3};
use source::ChannelVolume;
use std::fmt::Debug;
use std::time::Duration;
use Sample;
use 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)]
pub struct Spatial<I>
where I: Source,
I::Item: Sample + Debug
where
I: Source,
I::Item: Sample + Debug,
{
input: ChannelVolume<I>,
}
impl<I> Spatial<I>
where I: Source,
I::Item: Sample + Debug
where
I: Source,
I::Item: Sample + Debug,
{
pub fn new(input: I, emitter_position: [f32; 3], left_ear: [f32; 3], right_ear: [f32; 3])
-> Spatial<I>
where I: Source,
I::Item: Sample
pub fn new(
input: I, emitter_position: [f32; 3], left_ear: [f32; 3], right_ear: [f32; 3],
) -> Spatial<I>
where
I: Source,
I::Item: Sample,
{
let mut ret = Spatial { input: ChannelVolume::new(input, vec![0.0, 0.0]) };
let mut ret = Spatial {
input: ChannelVolume::new(input, vec![0.0, 0.0]),
};
ret.set_positions(emitter_position, left_ear, right_ear);
ret
}
/// Sets the position of the emitter and ears in the 3D world.
pub fn set_positions(&mut self, emitter_pos: [f32; 3], left_ear: [f32; 3],
right_ear: [f32; 3]) {
pub fn set_positions(
&mut self, emitter_pos: [f32; 3], left_ear: [f32; 3], right_ear: [f32; 3],
) {
let emitter_position = Point3::from(emitter_pos);
let left_ear = Point3::from(left_ear);
let right_ear = Point3::from(right_ear);
@ -50,8 +57,9 @@ impl<I> Spatial<I>
}
impl<I> Iterator for Spatial<I>
where I: Source,
I::Item: Sample + Debug
where
I: Source,
I::Item: Sample + Debug,
{
type Item = I::Item;
@ -67,14 +75,16 @@ impl<I> Iterator for Spatial<I>
}
impl<I> ExactSizeIterator for Spatial<I>
where I: Source + ExactSizeIterator,
I::Item: Sample + Debug
where
I: Source + ExactSizeIterator,
I::Item: Sample + Debug,
{
}
impl<I> Source for Spatial<I>
where I: Source,
I::Item: Sample + Debug
where
I: Source,
I::Item: Sample + Debug,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -5,8 +5,9 @@ use Source;
/// Internal function that builds a `Speed` object.
pub fn speed<I>(input: I, factor: f32) -> Speed<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
Speed {
input: input,
@ -17,16 +18,18 @@ pub fn speed<I>(input: I, factor: f32) -> Speed<I>
/// Filter that modifies each sample by a given value.
#[derive(Clone, Debug)]
pub struct Speed<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
input: I,
factor: f32,
}
impl<I> Iterator for Speed<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
type Item = I::Item;
@ -42,14 +45,16 @@ impl<I> Iterator for Speed<I>
}
impl<I> ExactSizeIterator for Speed<I>
where I: Source + ExactSizeIterator,
I::Item: Sample
where
I: Source + ExactSizeIterator,
I::Item: Sample,
{
}
impl<I> Source for Speed<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
@ -72,8 +77,10 @@ impl<I> Source for Speed<I>
if let Some(duration) = self.input.total_duration() {
let as_ns = duration.as_secs() * 1000000000 + duration.subsec_nanos() as u64;
let new_val = (as_ns as f32 / self.factor) as u64;
Some(Duration::new(new_val / 1000000000, (new_val % 1000000000) as u32))
Some(Duration::new(
new_val / 1000000000,
(new_val % 1000000000) as u32,
))
} else {
None
}

View file

@ -44,8 +44,9 @@ impl<I> Stoppable<I> {
}
impl<I> Iterator for Stoppable<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
type Item = I::Item;
@ -65,8 +66,9 @@ impl<I> Iterator for Stoppable<I>
}
impl<I> Source for Stoppable<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -5,8 +5,9 @@ use Source;
/// Internal function that builds a `Repeat` object.
pub fn take_duration<I>(input: I, duration: Duration) -> TakeDuration<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
TakeDuration {
input: input,
@ -18,8 +19,9 @@ pub fn take_duration<I>(input: I, duration: Duration) -> TakeDuration<I>
/// A source that repeats the given source.
#[derive(Clone, Debug)]
pub struct TakeDuration<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
input: I,
remaining_duration: Duration,
@ -27,8 +29,9 @@ pub struct TakeDuration<I>
}
impl<I> TakeDuration<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
/// Returns the duration elapsed for each sample extracted.
#[inline]
@ -40,8 +43,9 @@ impl<I> TakeDuration<I>
}
impl<I> Iterator for TakeDuration<I>
where I: Source,
I::Item: Sample
where
I: Source,
I::Item: Sample,
{
type Item = <I as Iterator>::Item;
@ -50,12 +54,10 @@ impl<I> Iterator for TakeDuration<I>
if self.remaining_duration <= duration_per_sample {
None
} else {
if let Some(sample) = self.input.next() {
self.remaining_duration = self.remaining_duration - duration_per_sample;
Some(sample)
} else {
None
}
@ -66,15 +68,16 @@ impl<I> Iterator for TakeDuration<I>
}
impl<I> Source for TakeDuration<I>
where I: Iterator + Source,
I::Item: Sample
where
I: Iterator + Source,
I::Item: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
let remaining_nanosecs = self.remaining_duration.as_secs() * 1000000000 +
self.remaining_duration.subsec_nanos() as u64;
let remaining_samples = remaining_nanosecs * self.input.sample_rate() as u64 *
self.channels() as u64 / 1000000000;
let remaining_nanosecs = self.remaining_duration.as_secs() * 1000000000
+ self.remaining_duration.subsec_nanos() as u64;
let remaining_samples = remaining_nanosecs * self.input.sample_rate() as u64
* self.channels() as u64 / 1000000000;
if let Some(value) = self.input.current_frame_len() {
if (value as u64) < remaining_samples {
@ -105,7 +108,6 @@ impl<I> Source for TakeDuration<I>
} else {
Some(self.requested_duration)
}
} else {
None
}

View file

@ -17,9 +17,10 @@ use Source;
/// channels and samples rate have been passed to `new`.
#[derive(Clone)]
pub struct UniformSourceIterator<I, D>
where I: Source,
I::Item: Sample,
D: Sample
where
I: Source,
I::Item: Sample,
D: Sample,
{
inner: Option<DataConverter<ChannelCountConverter<SampleRateConverter<Take<I>>>, D>>,
target_channels: u16,
@ -28,13 +29,15 @@ pub struct UniformSourceIterator<I, D>
}
impl<I, D> UniformSourceIterator<I, D>
where I: Source,
I::Item: Sample,
D: Sample
where
I: Source,
I::Item: Sample,
D: Sample,
{
#[inline]
pub fn new(input: I, target_channels: u16, target_sample_rate: u32)
-> UniformSourceIterator<I, D> {
pub fn new(
input: I, target_channels: u16, target_sample_rate: u32,
) -> UniformSourceIterator<I, D> {
let total_duration = input.total_duration();
let input = UniformSourceIterator::bootstrap(input, target_channels, target_sample_rate);
@ -47,8 +50,9 @@ impl<I, D> UniformSourceIterator<I, D>
}
#[inline]
fn bootstrap(input: I, target_channels: u16, target_sample_rate: u32)
-> DataConverter<ChannelCountConverter<SampleRateConverter<Take<I>>>, D> {
fn bootstrap(
input: I, target_channels: u16, target_sample_rate: u32,
) -> DataConverter<ChannelCountConverter<SampleRateConverter<Take<I>>>, D> {
let frame_len = input.current_frame_len();
let from_channels = input.channels();
@ -58,10 +62,12 @@ impl<I, D> UniformSourceIterator<I, D>
iter: input,
n: frame_len,
};
let input = SampleRateConverter::new(input,
cpal::SampleRate(from_sample_rate),
cpal::SampleRate(target_sample_rate),
from_channels);
let input = SampleRateConverter::new(
input,
cpal::SampleRate(from_sample_rate),
cpal::SampleRate(target_sample_rate),
from_channels,
);
let input = ChannelCountConverter::new(input, from_channels, target_channels);
let input = DataConverter::new(input);
@ -70,9 +76,10 @@ impl<I, D> UniformSourceIterator<I, D>
}
impl<I, D> Iterator for UniformSourceIterator<I, D>
where I: Source,
I::Item: Sample,
D: Sample
where
I: Source,
I::Item: Sample,
D: Sample,
{
type Item = D;
@ -105,9 +112,10 @@ impl<I, D> Iterator for UniformSourceIterator<I, D>
}
impl<I, D> Source for UniformSourceIterator<I, D>
where I: Iterator + Source,
I::Item: Sample,
D: Sample
where
I: Iterator + Source,
I::Item: Sample,
D: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {
@ -137,7 +145,8 @@ struct Take<I> {
}
impl<I> Iterator for Take<I>
where I: Iterator
where
I: Iterator,
{
type Item = <I as Iterator>::Item;
@ -150,7 +159,6 @@ impl<I> Iterator for Take<I>
} else {
None
}
} else {
self.iter.next()
}
@ -169,7 +177,6 @@ impl<I> Iterator for Take<I>
};
(lower, upper)
} else {
self.iter.size_hint()
}
@ -177,6 +184,7 @@ impl<I> Iterator for Take<I>
}
impl<I> ExactSizeIterator for Take<I>
where I: ExactSizeIterator
where
I: ExactSizeIterator,
{
}

View file

@ -1,8 +1,7 @@
use Sample;
use Source;
use std::marker::PhantomData;
use std::time::Duration;
use Sample;
use Source;
/// An infinite source that produces zero.
#[derive(Clone, Debug)]
@ -24,7 +23,8 @@ impl<S> Zero<S> {
}
impl<S> Iterator for Zero<S>
where S: Sample
where
S: Sample,
{
type Item = S;
@ -35,7 +35,8 @@ impl<S> Iterator for Zero<S>
}
impl<S> Source for Zero<S>
where S: Sample
where
S: Sample,
{
#[inline]
fn current_frame_len(&self) -> Option<usize> {

View file

@ -1,13 +1,12 @@
use Device;
use Sample;
use Sink;
use Source;
use source::Spatial;
use std::f32;
use std::fmt::Debug;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use Device;
use Sample;
use Sink;
use Source;
pub struct SpatialSink {
sink: Sink,
@ -23,16 +22,16 @@ struct SoundPositions {
impl SpatialSink {
/// Builds a new `SpatialSink`.
#[inline]
pub fn new(device: &Device, emitter_position: [f32; 3], left_ear: [f32; 3],
right_ear: [f32; 3])
-> SpatialSink {
pub fn new(
device: &Device, emitter_position: [f32; 3], left_ear: [f32; 3], right_ear: [f32; 3],
) -> SpatialSink {
SpatialSink {
sink: Sink::new(device),
positions: Arc::new(Mutex::new(SoundPositions {
emitter_position,
left_ear,
right_ear,
})),
emitter_position,
left_ear,
right_ear,
})),
}
}
@ -54,19 +53,21 @@ impl SpatialSink {
/// Appends a sound to the queue of sounds to play.
#[inline]
pub fn append<S>(&self, source: S)
where S: Source + Send + 'static,
S::Item: Sample + Send + Debug
where
S: Source + Send + 'static,
S::Item: Sample + Send + Debug,
{
let positions = self.positions.clone();
let pos_lock = self.positions.lock().unwrap();
let source = Spatial::new(source,
pos_lock.emitter_position,
pos_lock.left_ear,
pos_lock.right_ear)
.periodic_access(Duration::from_millis(10), move |i| {
let pos = positions.lock().unwrap();
i.set_positions(pos.emitter_position, pos.left_ear, pos.right_ear);
});
let source = Spatial::new(
source,
pos_lock.emitter_position,
pos_lock.left_ear,
pos_lock.right_ear,
).periodic_access(Duration::from_millis(10), move |i| {
let pos = positions.lock().unwrap();
i.set_positions(pos.emitter_position, pos.left_ear, pos.right_ear);
});
self.sink.append(source);
}