diff --git a/src/conversions/sample.rs b/src/conversions/sample.rs index 95dde61..80f03b5 100644 --- a/src/conversions/sample.rs +++ b/src/conversions/sample.rs @@ -1,6 +1,4 @@ use std::marker::PhantomData; -use std::ops::Add; -use std::ops::AddAssign; use cpal; /// Converts the samples data type to `O`. @@ -65,16 +63,18 @@ impl ExactSizeIterator for DataConverter /// /// You can implement this trait on your own type as well if you wish so. /// -pub trait Sample: cpal::Sample + Add + AddAssign { +pub trait Sample: cpal::Sample { /// Linear interpolation between two samples. /// /// The result should be equal to /// `first * numerator / denominator + second * (1 - numerator / denominator)`. - // TODO: remove ; not necessary fn lerp(first: Self, second: Self, numerator: u32, denominator: u32) -> Self; /// Multiplies the value of this sample by the given amount. fn amplify(self, value: f32) -> Self; + /// Calls `saturating_add` on the sample. + fn saturating_add(self, other: Self) -> Self; + /// Returns the value corresponding to the absence of sound. fn zero_value() -> Self; @@ -100,6 +100,11 @@ impl Sample for u16 { self.to_i16().amplify(value).to_u16() } + #[inline] + fn saturating_add(self, other: u16) -> u16 { + self.saturating_add(other) + } + #[inline] fn zero_value() -> u16 { 32768 @@ -144,6 +149,11 @@ impl Sample for i16 { ((self as f32) * value) as i16 } + #[inline] + fn saturating_add(self, other: i16) -> i16 { + self.saturating_add(other) + } + #[inline] fn zero_value() -> i16 { 0 @@ -191,6 +201,11 @@ impl Sample for f32 { self * value } + #[inline] + fn saturating_add(self, other: f32) -> f32 { + self + other + } + #[inline] fn zero_value() -> f32 { 0.0 diff --git a/src/dynamic_mixer.rs b/src/dynamic_mixer.rs index 505a479..85617a0 100644 --- a/src/dynamic_mixer.rs +++ b/src/dynamic_mixer.rs @@ -106,7 +106,7 @@ impl Iterator for DynamicMixer where S: Sample + Send + 'static { let mut sum = S::zero_value(); for (num, src) in self.current_sources.iter_mut().enumerate() { if let Some(val) = src.next() { - sum += val; + sum = sum.saturating_add(val); } else { to_drop.push(num); } diff --git a/src/source/mix.rs b/src/source/mix.rs index 12f5bc4..d88701f 100644 --- a/src/source/mix.rs +++ b/src/source/mix.rs @@ -47,11 +47,10 @@ impl Iterator for Mix let s1 = self.input1.next(); let s2 = self.input2.next(); - // FIXME: shouldn't lerp, this is wrong match (s1, s2) { - (Some(s1), Some(s2)) => Some(Sample::lerp(s1, s2, 1, 2)), - (Some(s1), None) => Some(Sample::lerp(s1, Sample::zero_value(), 1, 2)), - (None, Some(s2)) => Some(Sample::lerp(s2, Sample::zero_value(), 1, 2)), + (Some(s1), Some(s2)) => Some(s1.saturating_add(s2)), + (Some(s1), None) => Some(s1), + (None, Some(s2)) => Some(s2), (None, None) => None, } }