mirror of
https://github.com/RustAudio/rodio
synced 2025-01-22 00:05:00 +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::fadein::FadeIn;
|
||||||
pub use self::mix::Mix;
|
pub use self::mix::Mix;
|
||||||
pub use self::pausable::Pausable;
|
pub use self::pausable::Pausable;
|
||||||
|
pub use self::periodic::PeriodicAccess;
|
||||||
pub use self::repeat::Repeat;
|
pub use self::repeat::Repeat;
|
||||||
pub use self::samples_converter::SamplesConverter;
|
pub use self::samples_converter::SamplesConverter;
|
||||||
pub use self::sine::SineWave;
|
pub use self::sine::SineWave;
|
||||||
|
@ -28,6 +29,7 @@ mod empty;
|
||||||
mod fadein;
|
mod fadein;
|
||||||
mod mix;
|
mod mix;
|
||||||
mod pausable;
|
mod pausable;
|
||||||
|
mod periodic;
|
||||||
mod repeat;
|
mod repeat;
|
||||||
mod samples_converter;
|
mod samples_converter;
|
||||||
mod sine;
|
mod sine;
|
||||||
|
@ -191,6 +193,15 @@ pub trait Source: Iterator
|
||||||
fadein::fadein(self, duration)
|
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.
|
/// Changes the play speed of the sound. Does not adjust the samples, only the play speed.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn speed(self, ratio: f32) -> Speed<Self>
|
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