fundsp/
realseq.rs

1//! Realtime safe backend for Sequencer.
2
3use super::audiounit::*;
4use super::buffer::*;
5use super::math::*;
6use super::sequencer::*;
7use super::signal::*;
8use thingbuf::mpsc::{channel, Receiver, Sender};
9
10#[derive(Default, Clone)]
11pub(crate) enum Message {
12    /// Reset the sequencer.
13    #[default]
14    Reset,
15    /// Add new event in absolute time.
16    Push(Event),
17    /// Add new event in relative time.
18    PushRelative(Event),
19    /// Edit event.
20    Edit(EventId, Edit),
21    /// Edit event in relative time.
22    EditRelative(EventId, Edit),
23}
24
25pub struct SequencerBackend {
26    /// For sending events for deallocation back to the frontend.
27    pub(crate) sender: Sender<Option<Event>>,
28    /// For receiving new events from the frontend.
29    receiver: Receiver<Message>,
30    /// The backend sequencer.
31    sequencer: Sequencer,
32}
33
34impl Clone for SequencerBackend {
35    fn clone(&self) -> Self {
36        // Allocate a dummy channel.
37        let (sender_1, _receiver_1) = channel(1);
38        let (_sender_2, receiver_2) = channel(1);
39        SequencerBackend {
40            sender: sender_1,
41            receiver: receiver_2,
42            sequencer: self.sequencer.clone(),
43        }
44    }
45}
46
47impl SequencerBackend {
48    /// Create new backend.
49    pub(crate) fn new(
50        sender: Sender<Option<Event>>,
51        receiver: Receiver<Message>,
52        sequencer: Sequencer,
53    ) -> Self {
54        Self {
55            sender,
56            receiver,
57            sequencer,
58        }
59    }
60
61    /// Handle changes made to the backend.
62    fn handle_messages(&mut self) {
63        while let Ok(message) = self.receiver.try_recv() {
64            match message {
65                Message::Reset => {
66                    self.reset();
67                }
68                Message::Push(event) => {
69                    self.sequencer.push_event(event);
70                }
71                Message::PushRelative(event) => {
72                    self.sequencer.push_relative_event(event);
73                }
74                Message::Edit(id, edit) => {
75                    self.sequencer.edit(id, edit.end_time, edit.fade_out);
76                }
77                Message::EditRelative(id, edit) => {
78                    self.sequencer
79                        .edit_relative(id, edit.end_time, edit.fade_out);
80                }
81            }
82        }
83    }
84
85    #[inline]
86    fn send_back_past(&mut self) {
87        while let Some(event) = self.sequencer.get_past_event() {
88            if self.sender.try_send(Some(event)).is_ok() {}
89        }
90    }
91}
92
93impl AudioUnit for SequencerBackend {
94    fn inputs(&self) -> usize {
95        0
96    }
97
98    fn outputs(&self) -> usize {
99        self.sequencer.outputs()
100    }
101
102    fn reset(&mut self) {
103        self.handle_messages();
104        if !self.sequencer.replay_events() {
105            while let Some(event) = self.sequencer.get_past_event() {
106                if self.sender.try_send(Some(event)).is_ok() {}
107            }
108            while let Some(event) = self.sequencer.get_ready_event() {
109                if self.sender.try_send(Some(event)).is_ok() {}
110            }
111            while let Some(event) = self.sequencer.get_active_event() {
112                if self.sender.try_send(Some(event)).is_ok() {}
113            }
114        }
115        self.sequencer.reset();
116    }
117
118    fn set_sample_rate(&mut self, sample_rate: f64) {
119        self.handle_messages();
120        self.sequencer.set_sample_rate(sample_rate);
121    }
122
123    #[inline]
124    fn tick(&mut self, input: &[f32], output: &mut [f32]) {
125        self.handle_messages();
126        self.sequencer.tick(input, output);
127        // Tick and process are the only places where events may be pushed to the past vector.
128        if !self.sequencer.replay_events() {
129            self.send_back_past();
130        }
131    }
132
133    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
134        self.handle_messages();
135        self.sequencer.process(size, input, output);
136        // Tick and process are the only places where events may be pushed to the past vector.
137        if !self.sequencer.replay_events() {
138            self.send_back_past();
139        }
140    }
141
142    fn get_id(&self) -> u64 {
143        self.sequencer.get_id()
144    }
145
146    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
147        self.handle_messages();
148        self.sequencer.ping(probe, hash)
149    }
150
151    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
152        self.handle_messages();
153        self.sequencer.route(input, frequency)
154    }
155
156    fn footprint(&self) -> usize {
157        self.sequencer.footprint()
158    }
159
160    fn allocate(&mut self) {
161        self.sequencer.allocate();
162    }
163}