chromaflock/Source/DSP/Filter.h

110 lines
3.1 KiB
C
Raw Normal View History

2026-07-13 20:57:38 +02:00
#pragma once
#include <cmath>
#include <algorithm>
enum class FilterType { LowPass12 = 0, LowPass24, BandPass, HighPass, Notch, NumTypes };
class Filter {
public:
void prepare(double sr) {
sampleRate = sr;
reset();
}
void reset() {
for (int i = 0; i < 4; ++i) {
stage[i] = 0.0f;
}
}
void setCoefficients(float cutoff, float res, FilterType type) {
cutoff = std::clamp(cutoff, 20.0f, static_cast<float>(sampleRate * 0.49));
resonance = std::clamp(res, 0.0f, 1.0f);
filterType = type;
float g = std::tan(static_cast<float>(pi) * cutoff / static_cast<float>(sampleRate));
float k = 2.0f - 2.0f * resonance;
float a1 = 1.0f / (1.0f + g * (g + k));
float a2 = g * a1;
gCoeff = g;
kCoeff = k;
m0 = 0.0f;
m1 = 0.0f;
m2 = 0.0f;
m3 = 0.0f;
switch (filterType) {
case FilterType::LowPass12:
m0 = 0.0f; m1 = 0.0f; m2 = a2; m3 = 0.0f;
break;
case FilterType::LowPass24:
m0 = 0.0f; m1 = 0.0f; m2 = 0.0f; m3 = a2 * a2;
break;
case FilterType::BandPass:
m0 = 0.0f; m1 = a2; m2 = 0.0f; m3 = 0.0f;
break;
case FilterType::HighPass:
m0 = 1.0f; m1 = -a1; m2 = -a2; m3 = 0.0f;
break;
case FilterType::Notch:
m0 = 1.0f; m1 = -a1 * k; m2 = -a2; m3 = 0.0f;
break;
case FilterType::NumTypes:
break;
}
}
float process(float input) {
float denom = 1.0f + kCoeff * gCoeff + gCoeff * gCoeff;
float hp = (input - (kCoeff + gCoeff) * stage[0] - stage[1]) / denom;
float bp = gCoeff * hp + stage[0];
float lp = gCoeff * bp + stage[1];
stage[0] = gCoeff * hp + bp;
stage[1] = gCoeff * bp + lp;
float hp2 = (lp - (kCoeff + gCoeff) * stage[2] - stage[3]) / denom;
float bp2 = gCoeff * hp2 + stage[2];
float lp2 = gCoeff * bp2 + stage[3];
stage[2] = gCoeff * hp2 + bp2;
stage[3] = gCoeff * bp2 + lp2;
float output = 0.0f;
switch (filterType) {
case FilterType::LowPass12:
output = lp;
break;
case FilterType::LowPass24:
output = lp2;
break;
case FilterType::BandPass:
output = bp;
break;
case FilterType::HighPass:
output = hp;
break;
case FilterType::Notch:
output = input - bp;
break;
case FilterType::NumTypes:
output = input;
break;
}
return output;
}
private:
static constexpr float pi = 3.14159265358979323846f;
double sampleRate = 44100.0;
float stage[4] = {0.0f, 0.0f, 0.0f, 0.0f};
float gCoeff = 0.0f, kCoeff = 0.0f;
float m0 = 0.0f, m1 = 0.0f, m2 = 0.0f, m3 = 0.0f;
float resonance = 0.0f;
FilterType filterType = FilterType::LowPass12;
};