/* ============================================================================== LFO.h Created: 24 Jul 2026 Author: Armin ============================================================================== */ #pragma once #include enum class LFOWaveform : std::uint8_t { Sine, Triangle, Saw, Square }; /** A simple polyphonic LFO for modulation purposes. Outputs values in [-1, 1]. */ class ModLFO { public: void prepare(double newSampleRate) { sampleRate = newSampleRate; phase = 0.f; } void setRate(float hz) { rate = hz; if (!synced) currentHz = rate; } void setWaveform(LFOWaveform wf) { waveform = wf; } void setSync(bool shouldSync, double bpm, int syncDiv) { synced = shouldSync; if (synced && bpm > 0 && syncDiv > 0) currentHz = float(bpm) * float(syncDiv) / (60.f * 4.f); else currentHz = rate; } float getNextSample() { float increment = currentHz / float(sampleRate); float value = evaluate(phase); phase += increment; if (phase >= 1.f) phase -= 1.f; return value; } void reset() { phase = 0.f; } float getCurrentHz() const { return currentHz; } private: float evaluate(float p) const { switch (waveform) { case LFOWaveform::Sine: return std::sin(2.f * juce::MathConstants::pi * p); case LFOWaveform::Triangle: return 2.f * std::abs(2.f * p - 1.f) - 1.f; case LFOWaveform::Saw: return 2.f * p - 1.f; case LFOWaveform::Square: return p < 0.5f ? 1.f : -1.f; default: return std::sin(2.f * juce::MathConstants::pi * p); } } double sampleRate{ 44100 }; float phase{ 0.f }; float rate{ 1.f }; float currentHz{ 1.f }; LFOWaveform waveform{ LFOWaveform::Sine }; bool synced{ false }; };