Skip to main content

rill_core/traits/
processable.rs

1//! Processable trait and NodeVariant.
2
3use crate::math::Transcendental;
4use crate::queues::telemetry::TelemetryTx;
5use crate::time::ClockTick;
6use crate::traits::port::Port;
7use crate::traits::Node;
8use crate::traits::ProcessResult;
9
10// ============================================================================
11// ProcessContext
12// ============================================================================
13
14/// Processing context provided during signal graph execution.
15pub struct ProcessContext<'a> {
16    /// Current clock tick with sample-accurate timing information.
17    pub clock: &'a ClockTick,
18}
19
20// ============================================================================
21// Processable Trait
22// ============================================================================
23
24/// A node or component that can process a block of audio.
25///
26/// This is the main execution trait for the signal graph. Each node type
27/// (Source, Processor, Router, Sink) implements this via blanket impls
28/// that delegate to their respective `generate`/`process`/`route`/`consume`.
29pub trait Processable<T: Transcendental, const BUF_SIZE: usize> {
30    /// Process one block of audio samples.
31    ///
32    /// # Errors
33    /// Returns a [`ProcessError`](crate::traits::ProcessError) if processing fails.
34    fn process_block(&mut self, ctx: &mut ProcessContext) -> ProcessResult<()>;
35}
36
37// ============================================================================
38// Blanket Implementations
39// ============================================================================
40
41impl<T, const BUF_SIZE: usize> Processable<T, BUF_SIZE>
42    for Box<dyn crate::traits::Source<T, BUF_SIZE>>
43where
44    T: Transcendental,
45{
46    fn process_block(&mut self, ctx: &mut ProcessContext) -> ProcessResult<()> {
47        self.as_mut().generate(ctx.clock, &[], &[])
48    }
49}
50
51impl<T, const BUF_SIZE: usize> Processable<T, BUF_SIZE>
52    for Box<dyn crate::traits::Processor<T, BUF_SIZE>>
53where
54    T: Transcendental,
55{
56    fn process_block(&mut self, ctx: &mut ProcessContext) -> ProcessResult<()> {
57        self.as_mut().process(ctx.clock, &[], &[], &[], &[])
58    }
59}
60
61impl<T, const BUF_SIZE: usize> Processable<T, BUF_SIZE>
62    for Box<dyn crate::traits::Sink<T, BUF_SIZE>>
63where
64    T: Transcendental,
65{
66    fn process_block(&mut self, ctx: &mut ProcessContext) -> ProcessResult<()> {
67        self.as_mut().consume(ctx.clock, &[], &[], &[], &[])
68    }
69}
70
71impl<T, const BUF_SIZE: usize> Processable<T, BUF_SIZE>
72    for Box<dyn crate::traits::Router<T, BUF_SIZE>>
73where
74    T: Transcendental,
75{
76    fn process_block(&mut self, ctx: &mut ProcessContext) -> ProcessResult<()> {
77        (**self).route(ctx.clock, &[])
78    }
79}
80
81// ============================================================================
82// NodeVariant
83// ============================================================================
84
85/// A type-erased node that wraps any of the four node roles.
86///
87/// Dispatches `process_block` and `Node` methods to the inner node.
88pub enum NodeVariant<T: Transcendental, const BUF_SIZE: usize> {
89    /// Signal source node (generates audio).
90    Source(Box<dyn crate::traits::Source<T, BUF_SIZE>>),
91    /// Signal processor node (processes audio in-place).
92    Processor(Box<dyn crate::traits::Processor<T, BUF_SIZE>>),
93    /// Signal router node (routes signals between ports).
94    Router(Box<dyn crate::traits::Router<T, BUF_SIZE>>),
95    /// Signal sink node (consumes audio).
96    Sink(Box<dyn crate::traits::Sink<T, BUF_SIZE>>),
97}
98
99impl<T: Transcendental, const BUF_SIZE: usize> Processable<T, BUF_SIZE>
100    for NodeVariant<T, BUF_SIZE>
101{
102    fn process_block(&mut self, ctx: &mut ProcessContext) -> ProcessResult<()> {
103        match self {
104            NodeVariant::Source(src) => src.process_block(ctx),
105            NodeVariant::Processor(proc) => proc.process_block(ctx),
106            NodeVariant::Router(rt) => rt.process_block(ctx),
107            NodeVariant::Sink(sink) => sink.process_block(ctx),
108        }
109    }
110}
111
112impl<T: Transcendental, const BUF_SIZE: usize> NodeVariant<T, BUF_SIZE> {
113    /// Set the telemetry sender for the wrapped node.
114    pub fn set_telemetry_tx(&mut self, tx: TelemetryTx) {
115        match self {
116            NodeVariant::Source(src) => Node::set_telemetry_tx(src.as_mut(), tx),
117            NodeVariant::Processor(proc) => Node::set_telemetry_tx(proc.as_mut(), tx),
118            NodeVariant::Router(rt) => Node::set_telemetry_tx(rt.as_mut(), tx),
119            NodeVariant::Sink(sink) => Node::set_telemetry_tx(sink.as_mut(), tx),
120        }
121    }
122}
123
124// ============================================================================
125// Node for NodeVariant
126// ============================================================================
127
128impl<T: Transcendental, const BUF_SIZE: usize> Node<T, BUF_SIZE> for NodeVariant<T, BUF_SIZE> {
129    fn node_type_id(&self) -> crate::traits::NodeTypeId
130    where
131        Self: 'static + Sized,
132    {
133        unreachable!()
134    }
135    fn id(&self) -> crate::traits::NodeId {
136        match self {
137            NodeVariant::Source(src) => src.id(),
138            NodeVariant::Processor(proc) => proc.id(),
139            NodeVariant::Router(rt) => rt.id(),
140            NodeVariant::Sink(sink) => sink.id(),
141        }
142    }
143    fn set_id(&mut self, id: crate::traits::NodeId) {
144        match self {
145            NodeVariant::Source(src) => src.set_id(id),
146            NodeVariant::Processor(proc) => proc.set_id(id),
147            NodeVariant::Router(rt) => rt.set_id(id),
148            NodeVariant::Sink(sink) => sink.set_id(id),
149        }
150    }
151    fn metadata(&self) -> crate::traits::NodeMetadata {
152        match self {
153            NodeVariant::Source(src) => src.metadata(),
154            NodeVariant::Processor(proc) => proc.metadata(),
155            NodeVariant::Router(rt) => rt.metadata(),
156            NodeVariant::Sink(sink) => sink.metadata(),
157        }
158    }
159    fn init(&mut self, sample_rate: f32) {
160        match self {
161            NodeVariant::Source(src) => src.init(sample_rate),
162            NodeVariant::Processor(proc) => proc.init(sample_rate),
163            NodeVariant::Router(rt) => rt.init(sample_rate),
164            NodeVariant::Sink(sink) => sink.init(sample_rate),
165        }
166    }
167    fn resolve_resources(&mut self, buffers: &crate::buffer::BufferRegistry<T>) {
168        match self {
169            NodeVariant::Source(src) => src.resolve_resources(buffers),
170            NodeVariant::Processor(proc) => proc.resolve_resources(buffers),
171            NodeVariant::Router(rt) => rt.resolve_resources(buffers),
172            NodeVariant::Sink(sink) => sink.resolve_resources(buffers),
173        }
174    }
175    fn resolve_backend(&mut self, backend: *mut dyn crate::io::IoBackend<T>) {
176        match self {
177            NodeVariant::Source(src) => src.resolve_backend(backend),
178            NodeVariant::Processor(proc) => proc.resolve_backend(backend),
179            NodeVariant::Router(rt) => rt.resolve_backend(backend),
180            NodeVariant::Sink(sink) => sink.resolve_backend(backend),
181        }
182    }
183    fn start(&mut self, handle: crate::traits::active::GraphHandle) {
184        match self {
185            NodeVariant::Source(src) => src.start(handle),
186            NodeVariant::Processor(proc) => proc.start(handle),
187            NodeVariant::Router(rt) => rt.start(handle),
188            NodeVariant::Sink(sink) => sink.start(handle),
189        }
190    }
191    fn stop(&mut self) {
192        match self {
193            NodeVariant::Source(src) => src.stop(),
194            NodeVariant::Processor(proc) => proc.stop(),
195            NodeVariant::Router(rt) => rt.stop(),
196            NodeVariant::Sink(sink) => sink.stop(),
197        }
198    }
199    fn reset(&mut self) {
200        match self {
201            NodeVariant::Source(src) => src.reset(),
202            NodeVariant::Processor(proc) => proc.reset(),
203            NodeVariant::Router(rt) => rt.reset(),
204            NodeVariant::Sink(sink) => sink.reset(),
205        }
206    }
207    fn get_parameter(&self, id: &crate::traits::ParameterId) -> Option<crate::traits::ParamValue> {
208        match self {
209            NodeVariant::Source(src) => src.get_parameter(id),
210            NodeVariant::Processor(proc) => proc.get_parameter(id),
211            NodeVariant::Router(rt) => rt.get_parameter(id),
212            NodeVariant::Sink(sink) => sink.get_parameter(id),
213        }
214    }
215    fn set_parameter(
216        &mut self,
217        id: &crate::traits::ParameterId,
218        value: crate::traits::ParamValue,
219    ) -> ProcessResult<()> {
220        match self {
221            NodeVariant::Source(src) => src.set_parameter(id, value),
222            NodeVariant::Processor(proc) => proc.set_parameter(id, value),
223            NodeVariant::Router(rt) => rt.set_parameter(id, value),
224            NodeVariant::Sink(sink) => sink.set_parameter(id, value),
225        }
226    }
227    fn input_port(&self, index: usize) -> Option<&Port<T, BUF_SIZE>> {
228        match self {
229            NodeVariant::Source(src) => src.input_port(index),
230            NodeVariant::Processor(proc) => proc.input_port(index),
231            NodeVariant::Router(rt) => rt.input_port(index),
232            NodeVariant::Sink(sink) => sink.input_port(index),
233        }
234    }
235    fn input_port_mut(&mut self, index: usize) -> Option<&mut Port<T, BUF_SIZE>> {
236        match self {
237            NodeVariant::Source(src) => src.input_port_mut(index),
238            NodeVariant::Processor(proc) => proc.input_port_mut(index),
239            NodeVariant::Router(rt) => rt.input_port_mut(index),
240            NodeVariant::Sink(sink) => sink.input_port_mut(index),
241        }
242    }
243    fn output_port(&self, index: usize) -> Option<&Port<T, BUF_SIZE>> {
244        match self {
245            NodeVariant::Source(src) => src.output_port(index),
246            NodeVariant::Processor(proc) => proc.output_port(index),
247            NodeVariant::Router(rt) => rt.output_port(index),
248            NodeVariant::Sink(sink) => sink.output_port(index),
249        }
250    }
251    fn output_port_mut(&mut self, index: usize) -> Option<&mut Port<T, BUF_SIZE>> {
252        match self {
253            NodeVariant::Source(src) => src.output_port_mut(index),
254            NodeVariant::Processor(proc) => proc.output_port_mut(index),
255            NodeVariant::Router(rt) => rt.output_port_mut(index),
256            NodeVariant::Sink(sink) => sink.output_port_mut(index),
257        }
258    }
259    fn control_port(&self, index: usize) -> Option<&Port<T, BUF_SIZE>> {
260        match self {
261            NodeVariant::Source(src) => src.control_port(index),
262            NodeVariant::Processor(proc) => proc.control_port(index),
263            NodeVariant::Router(rt) => rt.control_port(index),
264            NodeVariant::Sink(sink) => sink.control_port(index),
265        }
266    }
267    fn control_port_mut(&mut self, index: usize) -> Option<&mut Port<T, BUF_SIZE>> {
268        match self {
269            NodeVariant::Source(src) => src.control_port_mut(index),
270            NodeVariant::Processor(proc) => proc.control_port_mut(index),
271            NodeVariant::Router(rt) => rt.control_port_mut(index),
272            NodeVariant::Sink(sink) => sink.control_port_mut(index),
273        }
274    }
275    fn num_signal_inputs(&self) -> usize {
276        match self {
277            NodeVariant::Source(src) => {
278                let n: &dyn Node<T, BUF_SIZE> = &**src;
279                n.num_signal_inputs()
280            }
281            NodeVariant::Processor(proc) => {
282                let n: &dyn Node<T, BUF_SIZE> = &**proc;
283                n.num_signal_inputs()
284            }
285            NodeVariant::Router(rt) => {
286                let n: &dyn Node<T, BUF_SIZE> = &**rt;
287                n.num_signal_inputs()
288            }
289            NodeVariant::Sink(sink) => {
290                let n: &dyn Node<T, BUF_SIZE> = &**sink;
291                n.num_signal_inputs()
292            }
293        }
294    }
295    fn num_signal_outputs(&self) -> usize {
296        match self {
297            NodeVariant::Source(src) => {
298                let n: &dyn Node<T, BUF_SIZE> = &**src;
299                n.num_signal_outputs()
300            }
301            NodeVariant::Processor(proc) => {
302                let n: &dyn Node<T, BUF_SIZE> = &**proc;
303                n.num_signal_outputs()
304            }
305            NodeVariant::Router(rt) => {
306                let n: &dyn Node<T, BUF_SIZE> = &**rt;
307                n.num_signal_outputs()
308            }
309            NodeVariant::Sink(sink) => {
310                let n: &dyn Node<T, BUF_SIZE> = &**sink;
311                n.num_signal_outputs()
312            }
313        }
314    }
315    fn num_control_inputs(&self) -> usize {
316        match self {
317            NodeVariant::Source(src) => {
318                let n: &dyn Node<T, BUF_SIZE> = &**src;
319                n.num_control_inputs()
320            }
321            NodeVariant::Processor(proc) => {
322                let n: &dyn Node<T, BUF_SIZE> = &**proc;
323                n.num_control_inputs()
324            }
325            NodeVariant::Router(rt) => {
326                let n: &dyn Node<T, BUF_SIZE> = &**rt;
327                n.num_control_inputs()
328            }
329            NodeVariant::Sink(sink) => {
330                let n: &dyn Node<T, BUF_SIZE> = &**sink;
331                n.num_control_inputs()
332            }
333        }
334    }
335    fn num_control_outputs(&self) -> usize {
336        match self {
337            NodeVariant::Source(src) => {
338                let n: &dyn Node<T, BUF_SIZE> = &**src;
339                n.num_control_outputs()
340            }
341            NodeVariant::Processor(proc) => {
342                let n: &dyn Node<T, BUF_SIZE> = &**proc;
343                n.num_control_outputs()
344            }
345            NodeVariant::Router(rt) => {
346                let n: &dyn Node<T, BUF_SIZE> = &**rt;
347                n.num_control_outputs()
348            }
349            NodeVariant::Sink(sink) => {
350                let n: &dyn Node<T, BUF_SIZE> = &**sink;
351                n.num_control_outputs()
352            }
353        }
354    }
355    fn num_clock_inputs(&self) -> usize {
356        match self {
357            NodeVariant::Source(src) => {
358                let n: &dyn Node<T, BUF_SIZE> = &**src;
359                n.num_clock_inputs()
360            }
361            NodeVariant::Processor(proc) => {
362                let n: &dyn Node<T, BUF_SIZE> = &**proc;
363                n.num_clock_inputs()
364            }
365            NodeVariant::Router(rt) => {
366                let n: &dyn Node<T, BUF_SIZE> = &**rt;
367                n.num_clock_inputs()
368            }
369            NodeVariant::Sink(sink) => {
370                let n: &dyn Node<T, BUF_SIZE> = &**sink;
371                n.num_clock_inputs()
372            }
373        }
374    }
375    fn num_clock_outputs(&self) -> usize {
376        match self {
377            NodeVariant::Source(src) => {
378                let n: &dyn Node<T, BUF_SIZE> = &**src;
379                n.num_clock_outputs()
380            }
381            NodeVariant::Processor(proc) => {
382                let n: &dyn Node<T, BUF_SIZE> = &**proc;
383                n.num_clock_outputs()
384            }
385            NodeVariant::Router(rt) => {
386                let n: &dyn Node<T, BUF_SIZE> = &**rt;
387                n.num_clock_outputs()
388            }
389            NodeVariant::Sink(sink) => {
390                let n: &dyn Node<T, BUF_SIZE> = &**sink;
391                n.num_clock_outputs()
392            }
393        }
394    }
395    fn num_feedback_ports(&self) -> usize {
396        match self {
397            NodeVariant::Source(src) => {
398                let n: &dyn Node<T, BUF_SIZE> = &**src;
399                n.num_feedback_ports()
400            }
401            NodeVariant::Processor(proc) => {
402                let n: &dyn Node<T, BUF_SIZE> = &**proc;
403                n.num_feedback_ports()
404            }
405            NodeVariant::Router(rt) => {
406                let n: &dyn Node<T, BUF_SIZE> = &**rt;
407                n.num_feedback_ports()
408            }
409            NodeVariant::Sink(sink) => {
410                let n: &dyn Node<T, BUF_SIZE> = &**sink;
411                n.num_feedback_ports()
412            }
413        }
414    }
415    fn state(&self) -> &crate::traits::NodeState<T, BUF_SIZE> {
416        match self {
417            NodeVariant::Source(src) => src.state(),
418            NodeVariant::Processor(proc) => proc.state(),
419            NodeVariant::Router(rt) => rt.state(),
420            NodeVariant::Sink(sink) => sink.state(),
421        }
422    }
423    fn state_mut(&mut self) -> &mut crate::traits::NodeState<T, BUF_SIZE> {
424        match self {
425            NodeVariant::Source(src) => src.state_mut(),
426            NodeVariant::Processor(proc) => proc.state_mut(),
427            NodeVariant::Router(rt) => rt.state_mut(),
428            NodeVariant::Sink(sink) => sink.state_mut(),
429        }
430    }
431}