mirror of
https://codeberg.org/armin/justasample.git
synced 2026-09-01 04:10:48 +02:00
97 lines
2 KiB
C
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 };
|
||
|
|
};
|