mirror of
https://github.com/RustAudio/rodio
synced 2024-12-13 13:42:34 +00:00
Add Source::periodic_access
This commit is contained in:
parent
f0fed7ccb9
commit
83bcd1c175
2 changed files with 99 additions and 0 deletions
|
@ -11,6 +11,7 @@ pub use self::empty::Empty;
|
|||
pub use self::fadein::FadeIn;
|
||||
pub use self::mix::Mix;
|
||||
pub use self::pausable::Pausable;
|
||||
pub use self::periodic::PeriodicAccess;
|
||||
pub use self::repeat::Repeat;
|
||||
pub use self::samples_converter::SamplesConverter;
|
||||
pub use self::sine::SineWave;
|
||||
|
@ -28,6 +29,7 @@ mod empty;
|
|||
mod fadein;
|
||||
mod mix;
|
||||
mod pausable;
|
||||
mod periodic;
|
||||
mod repeat;
|
||||
mod samples_converter;
|
||||
mod sine;
|
||||
|
@ -191,6 +193,15 @@ pub trait Source: Iterator
|
|||
fadein::fadein(self, duration)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
{
|
||||
periodic::periodic(self, period, access)
|
||||
}
|
||||
|
||||
/// Changes the play speed of the sound. Does not adjust the samples, only the play speed.
|
||||
#[inline]
|
||||
fn speed(self, ratio: f32) -> Speed<Self>
|
||||
|
|
88
src/source/periodic.rs
Normal file
88
src/source/periodic.rs
Normal file
|
@ -0,0 +1,88 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use Sample;
|
||||
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,
|
||||
{
|
||||
// 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_frequency = (update_ms * source.samples_rate()) / 1000;
|
||||
|
||||
PeriodicAccess {
|
||||
input: source,
|
||||
modifier: modifier,
|
||||
update_frequency: update_frequency,
|
||||
samples_until_update: update_frequency,
|
||||
}
|
||||
}
|
||||
|
||||
/// Calls a function on a source every time a period elapsed.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PeriodicAccess<I, F> {
|
||||
// The inner source.
|
||||
input: I,
|
||||
|
||||
// Closure that gets access to `inner`.
|
||||
modifier: F,
|
||||
|
||||
// The frequency with which local_volume should be updated by remote_volume
|
||||
update_frequency: u32,
|
||||
|
||||
// How many samples remain until it is time to update local_volume with remote_volume.
|
||||
samples_until_update: u32,
|
||||
}
|
||||
|
||||
impl<I, F> Iterator for PeriodicAccess<I, F>
|
||||
where I: Source,
|
||||
I::Item: Sample,
|
||||
F: FnMut(&mut I)
|
||||
{
|
||||
type Item = I::Item;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<I::Item> {
|
||||
self.samples_until_update -= 1;
|
||||
if self.samples_until_update == 0 {
|
||||
(self.modifier)(&mut self.input);
|
||||
self.samples_until_update = self.update_frequency;
|
||||
}
|
||||
|
||||
self.input.next()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.input.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, F> Source for PeriodicAccess<I, F>
|
||||
where I: Source,
|
||||
I::Item: Sample,
|
||||
F: FnMut(&mut I)
|
||||
{
|
||||
#[inline]
|
||||
fn current_frame_len(&self) -> Option<usize> {
|
||||
self.input.current_frame_len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn channels(&self) -> u16 {
|
||||
self.input.channels()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn samples_rate(&self) -> u32 {
|
||||
self.input.samples_rate()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn total_duration(&self) -> Option<Duration> {
|
||||
self.input.total_duration()
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue