Skip to content

Instantly share code, notes, and snippets.

@chbtoys
Created July 17, 2022 09:55
Show Gist options
  • Save chbtoys/926ef26ace2eb9069a3a3d7d083efe48 to your computer and use it in GitHub Desktop.
Save chbtoys/926ef26ace2eb9069a3a3d7d083efe48 to your computer and use it in GitHub Desktop.
audio programming - beginner level
#ifndef MOOG_H
#define MOOG_H
#define MOOG_PI 3.14159265358979323846264338327950288
#include <vector>
namespace Moog
{
class MoogFilter
{
public:
MoogFilter(float sampleRate) : sampleRate(sampleRate)
{
memset(stage, 0, sizeof(stage));
memset(delay, 0, sizeof(delay));
SetCutoff(1000.0f);
SetResonance(0.10f);
}
~MoogFilter() {}
void Process(std::vector<float>& samples, uint32_t n)
{
for (int s = 0; s < n; ++s)
{
float x = samples[s] - resonance * stage[3];
// Four cascaded one-pole filters (bilinear transform)
stage[0] = x * p + delay[0] * p - k * stage[0];
stage[1] = stage[0] * p + delay[1] * p - k * stage[1];
stage[2] = stage[1] * p + delay[2] * p - k * stage[2];
stage[3] = stage[2] * p + delay[3] * p - k * stage[3];
// Clipping band-limited sigmoid
stage[3] -= (stage[3] * stage[3] * stage[3]) / 6.0;
delay[0] = x;
delay[1] = stage[0];
delay[2] = stage[1];
delay[3] = stage[2];
samples[s] = stage[3];
}
}
void SetResonance(float r)
{
resonance = r * (t2 + 6.0 * t1) / (t2 - 6.0 * t1);
}
void SetCutoff(float c)
{
cutoff = 2.0 * c / sampleRate;
p = cutoff * (1.8 - 0.8 * cutoff);
k = 2.0 * sin(cutoff * MOOG_PI * 0.5) - 1.0;
t1 = (1.0 - p) * 1.386249;
t2 = 12.0 + t1 * t1;
SetResonance(resonance);
}
float GetResonance() { return resonance; }
float GetCutoff() { return cutoff; }
private:
double stage[4];
double delay[4];
double p;
double k;
double t1;
double t2;
protected:
float cutoff;
float resonance;
float sampleRate;
};
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment