mirror of
https://github.com/RustAudio/rodio
synced 2024-09-20 06:02:00 +00:00
Have reworked ramp logic
All tests pass, the "lerp" function doesn't seem to work, I want to look into this further.
This commit is contained in:
parent
e01ca090dd
commit
52dc4a5f5f
3 changed files with 66 additions and 18 deletions
|
@ -5,9 +5,11 @@ use cpal::FromSample;
|
|||
use crate::source::{FadeIn, Mix, TakeDuration};
|
||||
use crate::{Sample, Source};
|
||||
|
||||
/// Mixes one sound fading out with another sound fading in for the given duration.
|
||||
/// 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.
|
||||
/// Only the crossfaded portion (beginning of fadeout, beginning of fadein) is
|
||||
/// returned.
|
||||
pub fn crossfade<I1, I2>(
|
||||
input_fadeout: I1,
|
||||
input_fadein: I2,
|
||||
|
@ -37,7 +39,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_crossfade() {
|
||||
fn test_crossfade_with_self() {
|
||||
let source1 = dummysource(10);
|
||||
let source2 = dummysource(10);
|
||||
let mut mixed = crossfade(
|
||||
|
@ -51,7 +53,10 @@ mod tests {
|
|||
assert_eq!(mixed.next(), Some(4.0));
|
||||
assert_eq!(mixed.next(), Some(5.0));
|
||||
assert_eq!(mixed.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_crossfade() {
|
||||
let source1 = dummysource(10);
|
||||
let source2 = dummysource(10).amplify(0.0);
|
||||
let mut mixed = crossfade(
|
||||
|
|
|
@ -54,12 +54,12 @@ where
|
|||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<I::Item> {
|
||||
self.inner_mut().next()
|
||||
self.input.next()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.inner().size_hint()
|
||||
self.input.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ where
|
|||
I: Source,
|
||||
I::Item: Sample,
|
||||
{
|
||||
let duration_nanos = duration.as_secs_f32();
|
||||
let duration_nanos = duration.as_nanos() as f32;
|
||||
assert!(duration_nanos > 0.0f32);
|
||||
|
||||
LinearGainRamp {
|
||||
|
@ -77,7 +77,7 @@ where
|
|||
let factor: f32;
|
||||
let remaining_ns = self.total_ns - self.elapsed_ns;
|
||||
|
||||
if remaining_ns <= 0.0 {
|
||||
if remaining_ns < 0.0 {
|
||||
if self.clamp_end {
|
||||
factor = self.end_gain;
|
||||
} else {
|
||||
|
@ -85,18 +85,14 @@ where
|
|||
}
|
||||
} else {
|
||||
self.sample_idx += 1;
|
||||
|
||||
factor = f32::lerp(
|
||||
self.start_gain,
|
||||
self.end_gain,
|
||||
remaining_ns as u32,
|
||||
self.total_ns as u32,
|
||||
);
|
||||
|
||||
let p = self.elapsed_ns / self.total_ns;
|
||||
factor = self.start_gain * (1.0f32 - p) + self.end_gain * p;
|
||||
}
|
||||
|
||||
// FIXME: the way this use to work was calculating a new elapsed value for every sample,
|
||||
// but this is not exactly correct for multichannel inputs. This is a new implementation
|
||||
// but it is presently causing the crossfade unit tests to fail.
|
||||
println!("Factor: {}, remaining: {}, total: {}", factor, remaining_ns,
|
||||
self.total_ns);
|
||||
|
||||
if self.sample_idx % (self.channels() as u64) == 0 {
|
||||
self.elapsed_ns +=
|
||||
1000000000.0 / (self.input.sample_rate() as f32);
|
||||
|
@ -152,5 +148,52 @@ where
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use crate::buffer::SamplesBuffer;
|
||||
|
||||
fn dummysource(length: u8) -> SamplesBuffer<f32> {
|
||||
// shamelessly copied from crossfade.rs
|
||||
let data: Vec<f32> = (1..=length).map(f32::from).collect();
|
||||
SamplesBuffer::new(1, 1, data)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_linearramp() {
|
||||
let source1 = dummysource(10);
|
||||
let mut faded = linear_gain_ramp(source1,
|
||||
Duration::from_secs(4),
|
||||
0.0, 1.0, true);
|
||||
|
||||
assert_eq!(faded.next(), Some(0.0));
|
||||
assert_eq!(faded.next(), Some(0.5));
|
||||
assert_eq!(faded.next(), Some(1.5));
|
||||
assert_eq!(faded.next(), Some(3.0));
|
||||
assert_eq!(faded.next(), Some(5.0));
|
||||
assert_eq!(faded.next(), Some(6.0));
|
||||
assert_eq!(faded.next(), Some(7.0));
|
||||
assert_eq!(faded.next(), Some(8.0));
|
||||
assert_eq!(faded.next(), Some(9.0));
|
||||
assert_eq!(faded.next(), Some(10.0));
|
||||
assert_eq!(faded.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_linearramp_clamped() {
|
||||
let source1 = dummysource(10);
|
||||
let mut faded = linear_gain_ramp(source1,
|
||||
Duration::from_secs(4),
|
||||
0.0, 0.5, true);
|
||||
|
||||
assert_eq!(faded.next(), Some(0.0));
|
||||
assert_eq!(faded.next(), Some(0.25));
|
||||
assert_eq!(faded.next(), Some(0.75));
|
||||
assert_eq!(faded.next(), Some(1.5));
|
||||
assert_eq!(faded.next(), Some(2.5));
|
||||
assert_eq!(faded.next(), Some(3.0));
|
||||
assert_eq!(faded.next(), Some(3.5));
|
||||
assert_eq!(faded.next(), Some(4.0));
|
||||
assert_eq!(faded.next(), Some(4.5));
|
||||
assert_eq!(faded.next(), Some(5.0));
|
||||
assert_eq!(faded.next(), None);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue