rill_core_dsp/generators/
mod.rs1use rill_core::traits::algorithm::Algorithm;
15use rill_core::Transcendental;
16
17mod basic;
19mod envelope;
20mod fm;
21mod lfo;
22mod noise;
23mod reader;
24mod resampler;
25mod sample_player;
26mod wavetable;
27
28pub use basic::*;
30pub use envelope::*;
31pub use fm::*;
32pub use lfo::*;
33pub use noise::*;
34pub use reader::*;
35pub use resampler::*;
36pub use sample_player::*;
37pub use wavetable::*;
38
39pub trait Generator<T: Transcendental>: Algorithm<T> {
46 fn phase(&self) -> T;
48
49 fn set_phase(&mut self, phase: T);
51
52 fn reset_phase(&mut self) {
54 self.set_phase(T::ZERO);
55 }
56
57 fn frequency(&self) -> f32;
59
60 fn set_frequency(&mut self, freq: f32);
62
63 fn amplitude(&self) -> T;
65
66 fn set_amplitude(&mut self, amp: T);
68}
69
70pub trait SyncableGenerator<T: Transcendental>: Generator<T> {
75 fn sync(&mut self, reset: bool);
80
81 fn periods(&self) -> u32;
83}
84
85pub trait ModulatableGenerator<T: Transcendental>: Generator<T> {
90 fn modulate_frequency(&mut self, amount: T);
95
96 fn modulation_index(&self) -> T;
98
99 fn set_modulation_index(&mut self, index: T);
101}
102
103#[derive(Debug)]
109pub struct GeneratorComparison;
110
111impl GeneratorComparison {
112 pub fn harmonic_content() -> &'static str {
114 "Harmonic content:\n\
115 ┌────────────┬─────────────────────────────────┐\n\
116 │ Generator │ Spectrum │\n\
117 ├────────────┼─────────────────────────────────┤\n\
118 │ Sine │ Single harmonic (pure tone) │\n\
119 │ Triangle │ Odd harmonics, fast roll-off │\n\
120 │ Saw │ All harmonics (1/n) │\n\
121 │ Square │ Odd harmonics (1/n) │\n\
122 │ Pulse │ Depends on pulse width │\n\
123 │ White │ Uniform across all frequencies │\n\
124 │ Pink │ 3dB/octave roll-off (1/f) │\n\
125 │ Brown │ 6dB/octave roll-off (1/f²) │\n\
126 └────────────┴─────────────────────────────────┘"
127 }
128
129 pub fn usage_guide() -> &'static str {
131 "How to choose a generator:\n\n\
132 🎵 **Subtractive synthesis**:\n\
133 → Saw, Square, Pulse - rich spectrum for filtering\n\n\
134 🎵 **FM synthesis**:\n\
135 → Sine - pure tone for modulation\n\n\
136 🎵 **Additive synthesis**:\n\
137 → Sine (multiple) - building complex timbres\n\n\
138 🎵 **Noise effects**:\n\
139 → White - wind, snare drum\n\
140 → Pink - natural phenomena\n\
141 → Brown - thunder, rumble\n\n\
142 🎵 **Envelopes**:\n\
143 → ADSR - amplitude envelopes\n\
144 → AR - percussion\n\
145 → ASR - organ sounds\n\n\
146 🎵 **Modulation**:\n\
147 → LFO - vibrato, tremolo, filter sweep"
148 }
149
150 pub fn performance_guide() -> &'static str {
152 "Performance (relative):\n\
153 ⚡ **Sine** - 1x (fastest)\n\
154 ⚡⚡ **Triangle, Square** - 1.5x\n\
155 ⚡⚡⚡ **Saw** - 2x (with anti-aliasing)\n\
156 ⚡⚡⚡ **Noise** - 2x\n\
157 ⚡⚡⚡⚡ **Envelope** - 3x\n\
158 ⚡⚡⚡⚡ **FM Synth** - depends on operator count"
159 }
160}
161
162#[cfg(test)]
167mod tests {
168 use super::*;
169
170 #[test]
171 fn test_generator_trait_bounds() {
172 fn assert_generator<T: Transcendental, G: Generator<T>>() {}
174 fn assert_syncable<T: Transcendental, G: SyncableGenerator<T>>() {}
175 fn assert_modulatable<T: Transcendental, G: ModulatableGenerator<T>>() {}
176
177 assert_generator::<f32, BasicOscillator<f32>>();
178 assert_generator::<f32, NoiseGenerator<f32>>();
179 assert_generator::<f32, EnvelopeGenerator<f32>>();
180 assert_generator::<f32, LFO<f32>>();
181 assert_generator::<f32, SimpleFmSynth<f32>>();
182
183 assert_syncable::<f32, BasicOscillator<f32>>();
184 assert_modulatable::<f32, BasicOscillator<f32>>();
185 }
186
187 #[test]
188 fn test_comparison_guides() {
189 assert!(!GeneratorComparison::harmonic_content().is_empty());
190 assert!(!GeneratorComparison::usage_guide().is_empty());
191 assert!(!GeneratorComparison::performance_guide().is_empty());
192 }
193}