justasample/Source/Sampler/LFO.h
2026-08-02 22:07:29 +02:00

97 lines
2 KiB
C++

/*
==============================================================================
LFO.h
Created: 24 Jul 2026
Author: Armin
==============================================================================
*/
#pragma once
#include <JuceHeader.h>
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<float>::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<float>::pi * p);
}
}
double sampleRate{ 44100 };
float phase{ 0.f };
float rate{ 1.f };
float currentHz{ 1.f };
LFOWaveform waveform{ LFOWaveform::Sine };
bool synced{ false };
};