1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::{cell::RefCell, sync::Arc};
use crate::{frame, set, Controlled, Frame, Handle, Set, SetHandle, Signal, Stop};
pub struct MixerControl<'a, T>(&'a Mixer<T>);
impl<T> MixerControl<'_, T> {
pub fn play<S>(&mut self, signal: S) -> Handle<Stop<S>>
where
S: Signal<Frame = T> + Send + 'static,
{
let signal = Arc::new(Stop::new(signal));
let handle = unsafe { Handle::from_arc(signal.clone()) };
self.0.send.borrow_mut().insert(signal);
handle
}
}
pub struct Mixer<T> {
send: RefCell<SetHandle<ErasedSignal<T>>>,
recv: RefCell<Inner<T>>,
}
impl<T> Mixer<T>
where
T: Frame + Clone,
{
pub fn new() -> Self {
let (handle, set) = set();
Self {
send: RefCell::new(handle),
recv: RefCell::new(Inner {
set,
buffer: vec![T::ZERO; 1024].into(),
}),
}
}
}
impl<T> Default for Mixer<T>
where
T: Frame + Clone,
{
fn default() -> Self {
Self::new()
}
}
unsafe impl<'a, T: 'a> Controlled<'a> for Mixer<T> {
type Control = MixerControl<'a, T>;
unsafe fn make_control(signal: &'a Mixer<T>) -> Self::Control {
MixerControl(signal)
}
}
struct Inner<T> {
set: Set<ErasedSignal<T>>,
buffer: Box<[T]>,
}
impl<T: Frame> Signal for Mixer<T> {
type Frame = T;
fn sample(&self, interval: f32, out: &mut [T]) {
let this = &mut *self.recv.borrow_mut();
this.set.update();
for o in out.iter_mut() {
*o = T::ZERO;
}
for i in (0..this.set.len()).rev() {
let signal = &this.set[i];
if signal.remaining() < 0.0 {
signal.stop();
}
if signal.is_stopped() {
this.set.remove(i);
continue;
}
if signal.is_paused() {
continue;
}
let mut iter = out.iter_mut();
while iter.len() > 0 {
let n = iter.len().min(this.buffer.len());
let staging = &mut this.buffer[..n];
signal.sample(interval, staging);
for (staged, o) in staging.iter().zip(&mut iter) {
*o = frame::mix(o, staged);
}
}
}
}
}
type ErasedSignal<T> = Arc<Stop<dyn Signal<Frame = T>>>;