use rill_core::traits::algorithm::Algorithm;
use rill_core::Transcendental;
mod basic;
mod envelope;
mod fm;
mod lfo;
mod noise;
mod reader;
mod resampler;
mod sample_player;
mod wavetable;
pub use basic::*;
pub use envelope::*;
pub use fm::*;
pub use lfo::*;
pub use noise::*;
pub use reader::*;
pub use resampler::*;
pub use sample_player::*;
pub use wavetable::*;
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 {
"Harmonic content:\n\
┌────────────┬─────────────────────────────────┐\n\
│ Generator │ Spectrum │\n\
├────────────┼─────────────────────────────────┤\n\
│ Sine │ Single harmonic (pure tone) │\n\
│ Triangle │ Odd harmonics, fast roll-off │\n\
│ Saw │ All harmonics (1/n) │\n\
│ Square │ Odd harmonics (1/n) │\n\
│ Pulse │ Depends on pulse width │\n\
│ White │ Uniform across all frequencies │\n\
│ Pink │ 3dB/octave roll-off (1/f) │\n\
│ Brown │ 6dB/octave roll-off (1/f²) │\n\
└────────────┴─────────────────────────────────┘"
}
pub fn usage_guide() -> &'static str {
"How to choose a generator:\n\n\
🎵 **Subtractive synthesis**:\n\
→ Saw, Square, Pulse - rich spectrum for filtering\n\n\
🎵 **FM synthesis**:\n\
→ Sine - pure tone for modulation\n\n\
🎵 **Additive synthesis**:\n\
→ Sine (multiple) - building complex timbres\n\n\
🎵 **Noise effects**:\n\
→ White - wind, snare drum\n\
→ Pink - natural phenomena\n\
→ Brown - thunder, rumble\n\n\
🎵 **Envelopes**:\n\
→ ADSR - amplitude envelopes\n\
→ AR - percussion\n\
→ ASR - organ sounds\n\n\
🎵 **Modulation**:\n\
→ LFO - vibrato, tremolo, filter sweep"
}
pub fn performance_guide() -> &'static str {
"Performance (relative):\n\
⚡ **Sine** - 1x (fastest)\n\
⚡⚡ **Triangle, Square** - 1.5x\n\
⚡⚡⚡ **Saw** - 2x (with anti-aliasing)\n\
⚡⚡⚡ **Noise** - 2x\n\
⚡⚡⚡⚡ **Envelope** - 3x\n\
⚡⚡⚡⚡ **FM Synth** - depends on operator count"
}
}
#[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());
}
}