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
//! # Eurorack — modular processing case archetype
//!
//! An `Eurorack` is a single processing unit (case) in a modular
//! signal processing system — equivalent to one row or enclosure in a Eurorack
//! modular synthesizer.
//!
//! Each case holds:
//! - **Signal processing modules** — signal generation, transformation, routing, consumption
//! - **Control modules** — automata (LFO, envelope), sensors (OSC)
//! - **Signal routing** — port-to-port connections between modules
//!
//! ## Domain
//!
//! Eurorack is a modular synthesizer format standardised by Doepfer
//! in 1996. Modules are mounted in cases (rows) that provide power
//! and a backplane for patching. Multiple cases are patched together
//! via a [`ModularSystem`](super::super::ModularSystem) to form
//! a complete instrument.
//!
//! ## Hierarchy
//!
//! ```text
//! ModularSystem (ActorSystem)
//! └── RackCase: Eurorack (case 1)
//! ├── Graph (nodes: Source, Processor, Router, Sink)
//! └── Patchbay (modules: Servo, Sensor)
//! ```
/// A single Eurorack processing case — holds signal and control modules,
/// provides the backplane (sample rate, clock, command routing).
///
/// This is the archetype for any Eurorack-compatible processing unit.
/// Concrete implementations ([`RackCase`]) are managed by a
/// [`ModularSystem`] which acts as an actor system for inter-case
/// communication.
///
/// # Example
///
/// ```no_run
/// use rill_core::traits::Eurorack;
///
/// struct MyCase {
/// name: String,
/// sample_rate: f32,
/// }
///
/// impl Eurorack for MyCase {
/// fn name(&self) -> &str { &self.name }
/// fn sample_rate(&self) -> f32 { self.sample_rate }
/// fn block_size(&self) -> usize { 256 }
/// }
/// ```