use crate::algorithm::{Algorithm, AlgorithmCategory, AlgorithmMetadata};
use rill_core::Transcendental;
mod basic;
mod envelope;
mod fm;
mod lfo;
mod noise;
pub use basic::*;
pub use envelope::*;
pub use fm::*;
pub use lfo::*;
pub use noise::*;
pub trait Generator<T: Transcendental>: Algorithm<T> {
fn phase(&self) -> T;
fn set_phase(&mut self, phase: T);
fn reset_phase(&mut self) {
self.set_phase(T::ZERO);
}
fn frequency(&self) -> f32;
fn set_frequency(&mut self, freq: f32);
fn amplitude(&self) -> T;
fn set_amplitude(&mut self, amp: T);
}
pub trait SyncableGenerator<T: Transcendental>: Generator<T> {
fn sync(&mut self, reset: bool);
fn periods(&self) -> u32;
}
pub trait ModulatableGenerator<T: Transcendental>: Generator<T> {
fn modulate_frequency(&mut self, amount: T);
fn modulation_index(&self) -> T;
fn set_modulation_index(&mut self, index: T);
}
#[derive(Debug)]
pub struct GeneratorComparison;
impl GeneratorComparison {
pub fn harmonic_content() -> &'static str {
"Гармонический состав:\n\
┌────────────┬─────────────────────────────────┐\n\
│ Генератор │ Спектр │\n\
├────────────┼─────────────────────────────────┤\n\
│ Sine │ Одна гармоника (чистый тон) │\n\
│ Triangle │ Нечётные, быстрое затухание │\n\
│ Saw │ Все гармоники (1/n) │\n\
│ Square │ Нечётные гармоники (1/n) │\n\
│ Pulse │ Зависит от ширины импульса │\n\
│ White │ Равномерный по всем частотам │\n\
│ Pink │ Спад 3dB/октаву (1/f) │\n\
│ Brown │ Спад 6dB/октаву (1/f²) │\n\
└────────────┴─────────────────────────────────┘"
}
pub fn usage_guide() -> &'static str {
"Как выбрать генератор:\n\n\
🎵 **Субтрактивный синтез**:\n\
→ Saw, Square, Pulse - богатый спектр для фильтрации\n\n\
🎵 **FM синтез**:\n\
→ Sine - чистый тон для модуляции\n\n\
🎵 **Аддитивный синтез**:\n\
→ Sine (множество) - построение сложных тембров\n\n\
🎵 **Шумовые эффекты**:\n\
→ White - ветер, snare drum\n\
→ Pink - естественные явления\n\
→ Brown - гром, рокот\n\n\
🎵 **Огибающие**:\n\
→ ADSR - амплитудные огибающие\n\
→ AR - перкуссия\n\
→ ASR - орга́нные звуки\n\n\
🎵 **Модуляция**:\n\
→ LFO - вибрато, тремоло, фильтр-свип"
}
pub fn performance_guide() -> &'static str {
"Производительность (относительная):\n\
⚡ **Sine** - 1x (самый быстрый)\n\
⚡⚡ **Triangle, Square** - 1.5x\n\
⚡⚡⚡ **Saw** - 2x (с анти-алиасингом)\n\
⚡⚡⚡ **Noise** - 2x\n\
⚡⚡⚡⚡ **Envelope** - 3x\n\
⚡⚡⚡⚡ **FM Synth** - зависит от числа операторов"
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_generator_trait_bounds() {
fn assert_generator<T: Transcendental, G: Generator<T>>() {}
fn assert_syncable<T: Transcendental, G: SyncableGenerator<T>>() {}
fn assert_modulatable<T: Transcendental, G: ModulatableGenerator<T>>() {}
assert_generator::<f32, BasicOscillator<f32>>();
assert_generator::<f32, NoiseGenerator<f32>>();
assert_generator::<f32, EnvelopeGenerator<f32>>();
assert_generator::<f32, LFO<f32>>();
assert_generator::<f32, SimpleFmSynth<f32>>();
assert_syncable::<f32, BasicOscillator<f32>>();
assert_modulatable::<f32, BasicOscillator<f32>>();
}
#[test]
fn test_comparison_guides() {
assert!(!GeneratorComparison::harmonic_content().is_empty());
assert!(!GeneratorComparison::usage_guide().is_empty());
assert!(!GeneratorComparison::performance_guide().is_empty());
}
}