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};

/// Handle for controlling a [`Mixer`] from another thread
///
/// Constructed by calling [`mixer`].
pub struct MixerControl<'a, T>(&'a Mixer<T>);

impl<T> MixerControl<'_, T> {
    /// Begin playing `signal`, returning a handle that can be used to pause or stop it and access
    /// other controls
    ///
    /// Finished signals are automatically stopped, and their storage reused for future `play`
    /// calls.
    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
    }
}

/// A [`Signal`] that mixes a dynamic set of [`Signal`]s
///
/// Constructed by calling [`mixer`].
pub struct Mixer<T> {
    send: RefCell<SetHandle<ErasedSignal<T>>>,
    recv: RefCell<Inner<T>>,
}

impl<T> Mixer<T>
where
    T: Frame + Clone,
{
    /// Construct a new mixer
    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;
            }

            // Sample into `buffer`, then mix into `out`
            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>>>;