From 5b97136f447897ba404e0362e0cf991a787b06e7 Mon Sep 17 00:00:00 2001 From: HiveBeats Date: Thu, 7 Sep 2023 23:53:29 +0400 Subject: [PATCH] wip: filter (lp, hp, bp) --- inc/BandPassFilter.h | 12 ++++++++++++ inc/Filter.h | 32 ++++++++++++++++++++++++++++++++ inc/HighPassFilter.h | 12 ++++++++++++ inc/LowPassFilter.h | 13 +++++++++++++ src/BandPassFilter.cpp | 17 +++++++++++++++++ src/Filter.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ src/HighPassFilter.cpp | 17 +++++++++++++++++ src/LowPassFilter.cpp | 22 ++++++++++++++++++++++ src/Synth.cpp | 2 ++ 9 files changed, 168 insertions(+) create mode 100644 inc/BandPassFilter.h create mode 100644 inc/Filter.h create mode 100644 inc/HighPassFilter.h create mode 100644 inc/LowPassFilter.h create mode 100644 src/BandPassFilter.cpp create mode 100644 src/Filter.cpp create mode 100644 src/HighPassFilter.cpp create mode 100644 src/LowPassFilter.cpp diff --git a/inc/BandPassFilter.h b/inc/BandPassFilter.h new file mode 100644 index 0000000..c53911f --- /dev/null +++ b/inc/BandPassFilter.h @@ -0,0 +1,12 @@ +#pragma once +#include "Filter.h" + +class BandPassFilter: public Filter +{ +private: + void calculate_coefficients() override; +public: + BandPassFilter(/* args */); + ~BandPassFilter(); +}; + diff --git a/inc/Filter.h b/inc/Filter.h new file mode 100644 index 0000000..79fac1c --- /dev/null +++ b/inc/Filter.h @@ -0,0 +1,32 @@ +#pragma once +#include "Effect.h" + +class Filter: public Effect +{ + + +protected: + struct Normals { + float V; + float K; + }; + + float m_freq; // cutoff frequency + float m_q; // filter quantity (resonance) + float m_order; // filter order (peakGain) + /* todo: filter adsr */ + float m_norm; + float m_a0, m_a1, m_a2, m_b1, m_b2; + float m_z1, m_z2; + Normals calculate_normals(); + virtual void calculate_coefficients(){}; +public: + Filter(/* args */); + ~Filter(); + void Trigger() override; + void Release() override; + float Process(float in); + void Process(std::vector& samples) override; + void SetParameters(float freq, float res, float q); +}; + diff --git a/inc/HighPassFilter.h b/inc/HighPassFilter.h new file mode 100644 index 0000000..fb0e5d0 --- /dev/null +++ b/inc/HighPassFilter.h @@ -0,0 +1,12 @@ +#pragma once +#include "Filter.h" + +class HighPassFilter: public Filter +{ +private: + void calculate_coefficients() override; +public: + HighPassFilter(/* args */); + ~HighPassFilter(); +}; + diff --git a/inc/LowPassFilter.h b/inc/LowPassFilter.h new file mode 100644 index 0000000..071c9f2 --- /dev/null +++ b/inc/LowPassFilter.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Filter.h" + +class LowPassFilter: public Filter +{ +protected: + void calculate_coefficients() override; +public: + LowPassFilter(/* args */); + ~LowPassFilter(); +}; + diff --git a/src/BandPassFilter.cpp b/src/BandPassFilter.cpp new file mode 100644 index 0000000..151b4de --- /dev/null +++ b/src/BandPassFilter.cpp @@ -0,0 +1,17 @@ +#include "BandPassFilter.h" + +BandPassFilter::BandPassFilter(/* args */) { +} + +BandPassFilter::~BandPassFilter() { +} + +void BandPassFilter::calculate_coefficients() { + Filter::Normals base = calculate_normals(); + m_norm = 1 / (1 + base.K / m_q + base.K * base.K); + m_a0 = base.K / m_q * m_norm; + m_a1 = 0; + m_a2 = -m_a0; + m_b1 = 2 * (base.K * base.K - 1) * m_norm; + m_b2 = (1 - base.K / m_q + base.K * base.K) * m_norm; +} \ No newline at end of file diff --git a/src/Filter.cpp b/src/Filter.cpp new file mode 100644 index 0000000..df54c67 --- /dev/null +++ b/src/Filter.cpp @@ -0,0 +1,41 @@ +#include "Filter.h" + +Filter::Filter(/* args */) { +} + +Filter::~Filter() { +} + +Filter::Normals Filter::calculate_normals() { + Filter::Normals res; + res.V = powf(10, fabs(m_order) / 20.0); + res.K = tanf(M_PI * m_freq); + + return res; +} + +void Filter::Trigger() { +} + +void Filter::Release() { +} + +float Filter::Process(float in) { + float out = in * m_a0 + m_z1; + m_z1 = in * m_a1 + m_z2 - m_b1 * out; + m_z2 = in * m_a2 - m_b2 * out; + return out; +} + +void Filter::Process(std::vector& samples) { + calculate_coefficients(); + for (std::size_t i = 0; i < samples.size(); i++) { + samples[i] = Process(samples[i]); + } +} + +void Filter::SetParameters(float freq, float res, float q) { + m_freq = freq; + m_q = res; + m_order = q; +} diff --git a/src/HighPassFilter.cpp b/src/HighPassFilter.cpp new file mode 100644 index 0000000..bc48cf9 --- /dev/null +++ b/src/HighPassFilter.cpp @@ -0,0 +1,17 @@ +#include "HighPassFilter.h" + +HighPassFilter::HighPassFilter(/* args */) { +} + +HighPassFilter::~HighPassFilter() { +} + +void HighPassFilter::calculate_coefficients() { + Filter::Normals base = calculate_normals(); + m_norm = 1 / (1 + base.K / m_q + base.K * base.K); + m_a0 = 1 * m_norm; + m_a1 = -2 * m_a0; + m_a2 = m_a0; + m_b1 = 2 * (base.K * base.K - 1) * m_norm; + m_b2 = (1 - base.K / m_q + base.K * base.K) * m_norm; +} \ No newline at end of file diff --git a/src/LowPassFilter.cpp b/src/LowPassFilter.cpp new file mode 100644 index 0000000..4720acc --- /dev/null +++ b/src/LowPassFilter.cpp @@ -0,0 +1,22 @@ +#include "LowPassFilter.h" +#include "Settings.h" + +LowPassFilter::LowPassFilter(/* args */) { + //todo: defaults + m_freq = 200.f / SAMPLE_RATE; + m_q = 0.707; + m_order = 0; +} + +LowPassFilter::~LowPassFilter() { +} + +void LowPassFilter::calculate_coefficients() { + Filter::Normals base = calculate_normals(); + m_norm = 1 / (1 + base.K / m_q + base.K * base.K); + m_a0 = base.K * base.K * m_norm; + m_a1 = 2 * m_a0; + m_a2 = m_a0; + m_b1 = 2 * (base.K * base.K - 1) * m_norm; + m_b2 = (1 - base.K / m_q + base.K * base.K) * m_norm; +} \ No newline at end of file diff --git a/src/Synth.cpp b/src/Synth.cpp index fc99405..b924043 100644 --- a/src/Synth.cpp +++ b/src/Synth.cpp @@ -4,11 +4,13 @@ #include "Logger.h" #include "OscillatorType.h" #include "Settings.h" +#include "LowPassFilter.h" Synth::Synth(/* args */) { add_oscillator(); add_oscillator(); AddEffect(new ADSR()); + AddEffect(new LowPassFilter()); for (size_t i = 0; i < STREAM_BUFFER_SIZE; i++) { float sample = 0.0f; m_out_signal.push_back(sample);