Skip to main content

rill_patchbay/automaton/
mod.rs

1//! # Автоматы — генеративные источники управления
2//!
3//! Модуль предоставляет различные типы автоматов для генерации
4//! управляющих сигналов в реальном времени.
5//!
6//! Автомат — это алгоритм с внутренним состоянием: он принимает
7//! время и текущее состояние, возвращает новое состояние и значение.
8//! Внешние воздействия на состояние не предполагаются.
9
10pub mod cellular;
11pub mod envelope;
12pub mod function;
13pub mod lfo;
14pub mod random;
15pub mod sequencer;
16
17pub use cellular::*;
18pub use envelope::*;
19pub use function::*;
20pub use lfo::*;
21pub use random::*;
22pub use sequencer::*;
23
24use std::fmt::Debug;
25
26// =============================================================================
27// Вспомогательные типы
28// =============================================================================
29
30/// Режим синхронизации автомата
31#[derive(Debug, Clone, Copy, PartialEq)]
32pub enum SyncMode {
33    Free,
34    Sync,
35    OneShot,
36}
37
38/// Диапазон значений автомата
39#[derive(Debug, Clone, Copy)]
40pub struct Range {
41    pub min: f64,
42    pub max: f64,
43}
44
45impl Range {
46    pub const fn new(min: f64, max: f64) -> Self {
47        Self { min, max }
48    }
49
50    pub const fn unipolar() -> Self {
51        Self { min: 0.0, max: 1.0 }
52    }
53
54    pub const fn bipolar() -> Self {
55        Self {
56            min: -1.0,
57            max: 1.0,
58        }
59    }
60
61    pub fn clamp(&self, value: f64) -> f64 {
62        value.clamp(self.min, self.max)
63    }
64
65    pub fn normalize(&self, value: f64) -> f64 {
66        (value - self.min) / (self.max - self.min)
67    }
68
69    pub fn denormalize(&self, norm: f64) -> f64 {
70        self.min + norm * (self.max - self.min)
71    }
72}
73
74// =============================================================================
75// Сравнение автоматов
76// =============================================================================
77
78/// Сводка характеристик автоматов
79#[derive(Debug)]
80pub struct AutomatonComparison;
81
82impl AutomatonComparison {
83    /// Сравнение типов автоматов
84    pub fn types() -> &'static str {
85        "Типы автоматов:\n\
86         ┌─────────────────┬─────────────────────────────┬─────────────────┐\n\
87         │ Автомат         │ Характеристики              │ Применение      │\n\
88         ├─────────────────┼─────────────────────────────┼─────────────────┤\n\
89         │ LFO             │ Гармонические/релаксационные│ Вибрато, тремоло│\n\
90         │ Envelope        │ ADSR, AR, ASR               │ Амплитудные ог. │\n\
91         │ Function        │ Произвольная функция времени│ Сложные модуляции│\n\
92         │ Sequencer       │ Паттерны, ступени           │ Ритмические     │\n\
93         │ RandomWalk      │ Случайные блуждания         │ Генеративные    │\n\
94         │ Chaos           │ Детерминированный хаос      │ Непредсказуемые │\n\
95         │ Cellular        │ Клеточные автоматы          │ Органические    │\n\
96         └─────────────────┴─────────────────────────────┴─────────────────┘"
97    }
98
99    /// Руководство по выбору автомата
100    pub fn selection_guide() -> &'static str {
101        "Как выбрать автомат:\n\n\
102         🎯 **Периодическая модуляция**:\n\
103         → LFO (Sine, Triangle, Saw, Square)\n\n\
104         🎯 **Однократные события**:\n\
105         → Envelope (ADSR, AR, ASR)\n\n\
106         🎯 **Сложные функции**:\n\
107         → Function с произвольным замыканием\n\n\
108         🎯 **Ритмические паттерны**:\n\
109         → Sequencer с шагами и длительностями\n\n\
110         🎯 **Генеративные процессы**:\n\
111         → RandomWalk, Chaos, Cellular\n\n\
112         🎯 **Случайные значения**:\n\
113         → Sample & Hold (LFO в режиме S&H)"
114    }
115
116    /// Производительность автоматов
117    pub fn performance_guide() -> &'static str {
118        "Производительность (относительная):\n\
119         ⚡ **Function** - 1x (простые функции)\n\
120         ⚡⚡ **LFO** - 2x (тригонометрия)\n\
121         ⚡⚡⚡ **Envelope** - 3x (логика переходов)\n\
122         ⚡⚡⚡ **RandomWalk** - 3x (RNG)\n\
123         ⚡⚡⚡⚡ **Sequencer** - 4x (паттерны)\n\
124         ⚡⚡⚡⚡ **Chaos** - 4x (итерации)\n\
125         ⚡⚡⚡⚡⚡ **Cellular** - 5x (соседи)"
126    }
127}
128
129// =============================================================================
130// Тесты
131// =============================================================================
132
133#[cfg(test)]
134mod tests {
135    use crate::control::Automaton as _;
136
137    #[test]
138    fn test_automaton_types_are_debug() {
139        // Проверяем, что все типы автоматов реализуют Debug (нужно для трейта)
140        fn assert_debug<T: std::fmt::Debug>(_: &T) {}
141        let lfo = super::LfoAutomaton::new("test", 1.0, 1.0, 0.0, super::LfoWaveform::Sine);
142        assert_debug(&lfo);
143        let env = super::EnvelopeAutomaton::adsr("test", 0.1, 0.2, 0.7, 0.3);
144        assert_debug(&env);
145        let func = super::FunctionAutomaton::new("test", |t| t);
146        assert_debug(&func);
147    }
148
149    #[test]
150    fn test_comparison_guides() {
151        assert!(!super::AutomatonComparison::types().is_empty());
152        assert!(!super::AutomatonComparison::selection_guide().is_empty());
153        assert!(!super::AutomatonComparison::performance_guide().is_empty());
154    }
155}