mirror of
https://github.com/RustAudio/rodio
synced 2024-12-13 13:42:34 +00:00
Use saturating_add for the samples, and fix the mixer
This commit is contained in:
parent
b1a560eb41
commit
e06f1f84e7
3 changed files with 23 additions and 9 deletions
|
@ -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<I, O> ExactSizeIterator for DataConverter<I, O>
|
|||
///
|
||||
/// 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
|
||||
|
|
|
@ -106,7 +106,7 @@ impl<S> Iterator for DynamicMixer<S> 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);
|
||||
}
|
||||
|
|
|
@ -47,11 +47,10 @@ impl<I1, I2> Iterator for Mix<I1, I2>
|
|||
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,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue