add Crossfade

This commit is contained in:
Daniel Lambert 2019-09-02 16:17:13 -05:00 committed by est31
parent e2f79f4a8b
commit 2c7d171670
2 changed files with 74 additions and 0 deletions

60
src/source/crossfade.rs Normal file
View file

@ -0,0 +1,60 @@
use std::time::Duration;
use Source;
use Sample;
use source::Mix;
use source::TakeDuration;
use source::FadeIn;
/// Mixes one sound fading out with another sound fading in for the given duration.
///
/// Only the crossfaded portion (beginning of fadeout, beginning of fadein) is returned.
pub fn crossfade<I1,I2>(input_fadeout: I1, input_fadein: I2, duration: Duration) -> Crossfade<I1,I2>
where
I1: Source,
I2: Source,
I1::Item: Sample,
I2::Item: Sample,
{
let mut input_fadeout = input_fadeout.take_duration(duration);
input_fadeout.set_filter_fadeout();
let input_fadein = input_fadein.take_duration(duration).fade_in(duration);
input_fadeout.mix(input_fadein)
}
pub type Crossfade<I1,I2> = Mix<TakeDuration<I1>,FadeIn<TakeDuration<I2>>>;
#[cfg(test)]
mod tests {
use super::*;
use 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
}
#[test]
fn test_crossfade() {
let source1 = dummysource(10);
let source2 = dummysource(10);
let mut mixed = crossfade(source1, source2, Duration::from_secs(5) + Duration::from_nanos(1));
assert_eq!(mixed.next(), Some(1.0));
assert_eq!(mixed.next(), Some(2.0));
assert_eq!(mixed.next(), Some(3.0));
assert_eq!(mixed.next(), Some(4.0));
assert_eq!(mixed.next(), Some(5.0));
assert_eq!(mixed.next(), None);
let source1 = dummysource(10);
let source2 = dummysource(10).amplify(0.0);
let mut mixed = crossfade(source1, source2, Duration::from_secs(5) + Duration::from_nanos(1));
assert_eq!(mixed.next(), Some(1.0 * 1.0));
assert_eq!(mixed.next(), Some(2.0 * 0.8));
assert_eq!(mixed.next(), Some(3.0 * 0.6));
assert_eq!(mixed.next(), Some(4.0 * 0.4));
assert_eq!(mixed.next(), Some(5.0 * 0.2));
assert_eq!(mixed.next(), None);
}
}

View file

@ -8,6 +8,7 @@ pub use self::amplify::Amplify;
pub use self::blt::BltFilter;
pub use self::buffered::Buffered;
pub use self::channel_volume::ChannelVolume;
pub use self::crossfade::Crossfade;
pub use self::delay::Delay;
pub use self::done::Done;
pub use self::empty::Empty;
@ -31,6 +32,7 @@ mod amplify;
mod blt;
mod buffered;
mod channel_volume;
mod crossfade;
mod delay;
mod done;
mod empty;
@ -202,6 +204,18 @@ where
amplify::amplify(self, value)
}
/// Mixes this sound fading out with another sound fading in for the given duration.
///
/// Only the crossfaded portion (beginning of self, beginning of other) is returned.
#[inline]
fn take_crossfade_with<S: Source>(self, other: S, duration: Duration) -> Crossfade<Self, S>
where
Self: Sized,
<S as Iterator>::Item: Sample,
{
crossfade::crossfade(self, other, duration)
}
/// Fades in the sound.
#[inline]
fn fade_in(self, duration: Duration) -> FadeIn<Self>