From 1636106bbef14fa34d062681fff3c54d5581e202 Mon Sep 17 00:00:00 2001 From: Daniel Jones Date: Sun, 12 Nov 2023 21:51:34 +0000 Subject: [PATCH] Add DCFilter node --- .../signalflow/node/processors/filters/dc.h | 26 +++++++++++ source/include/signalflow/signalflow.h | 1 + source/src/CMakeLists.txt | 1 + source/src/node/processors/filters/dc.cpp | 45 +++++++++++++++++++ source/src/python/nodes.cpp | 3 ++ 5 files changed, 76 insertions(+) create mode 100644 source/include/signalflow/node/processors/filters/dc.h create mode 100644 source/src/node/processors/filters/dc.cpp diff --git a/source/include/signalflow/node/processors/filters/dc.h b/source/include/signalflow/node/processors/filters/dc.h new file mode 100644 index 00000000..a8194fd2 --- /dev/null +++ b/source/include/signalflow/node/processors/filters/dc.h @@ -0,0 +1,26 @@ +#pragma once + +#include "signalflow/core/constants.h" +#include "signalflow/node/node.h" + +namespace signalflow +{ +/**--------------------------------------------------------------------------------* + * Remove DC offset. + *---------------------------------------------------------------------------------*/ +class DCFilter : public UnaryOpNode +{ +public: + DCFilter(NodeRef input = 0.0); + + virtual void process(Buffer &out, int num_frames) override; + virtual void alloc() override; + +private: + float R; + std::vector previous_input; + std::vector previous_output; +}; + +REGISTER(DCFilter, "dc-filter") +} diff --git a/source/include/signalflow/signalflow.h b/source/include/signalflow/signalflow.h index 6aeece21..8a3d248f 100644 --- a/source/include/signalflow/signalflow.h +++ b/source/include/signalflow/signalflow.h @@ -126,6 +126,7 @@ #include #include #include +#include #include #include #include diff --git a/source/src/CMakeLists.txt b/source/src/CMakeLists.txt index fd0c902c..3efa7c3f 100644 --- a/source/src/CMakeLists.txt +++ b/source/src/CMakeLists.txt @@ -56,6 +56,7 @@ set(SRC ${SRC} ${CMAKE_CURRENT_SOURCE_DIR}/node/processors/filters/svf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/node/processors/filters/eq.cpp ${CMAKE_CURRENT_SOURCE_DIR}/node/processors/filters/moog.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/node/processors/filters/dc.cpp ${CMAKE_CURRENT_SOURCE_DIR}/node/processors/panning/stereo-panner.cpp ${CMAKE_CURRENT_SOURCE_DIR}/node/processors/panning/stereo-balance.cpp ${CMAKE_CURRENT_SOURCE_DIR}/node/processors/panning/stereo-width.cpp diff --git a/source/src/node/processors/filters/dc.cpp b/source/src/node/processors/filters/dc.cpp new file mode 100644 index 00000000..20d5ff0b --- /dev/null +++ b/source/src/node/processors/filters/dc.cpp @@ -0,0 +1,45 @@ +#include "signalflow/core/graph.h" +#include "signalflow/node/processors/filters/dc.h" + +#include + +namespace signalflow +{ + +DCFilter::DCFilter(NodeRef input) + : UnaryOpNode(input) +{ + this->name = "dc-filter"; + + // "R" depends on sampling rate and the low frequency point. Do not set "R" to a fixed value + // (e.g. 0.99) if you don't know the sample rate. Instead set R to: + // (-3dB @ 40Hz): R = 1-(250/samplerate) + // (-3dB @ 30Hz): R = 1-(190/samplerate) + // (-3dB @ 20Hz): R = 1-(126/samplerate) + // this->R = 1.0 - (30.0 / this->get_graph()->get_sample_rate()); + + // this->alloc(); +} + +void DCFilter::alloc() +{ + this->previous_input.resize(this->num_output_channels_allocated); + this->previous_output.resize(this->num_output_channels_allocated); +} + +void DCFilter::process(Buffer &out, int num_frames) +{ + this->R = 1.0 - (30.0 / this->graph->get_sample_rate()); + for (int channel = 0; channel < num_output_channels; channel++) + { + for (int frame = 0; frame < num_frames; frame++) + { + float output = this->input->out[channel][frame] - this->previous_input[channel] + R * this->previous_output[channel]; + this->previous_input[channel] = this->input->out[channel][frame]; + this->previous_output[channel] = output; + out[channel][frame] = output; + } + } +} + +} diff --git a/source/src/python/nodes.cpp b/source/src/python/nodes.cpp index d8377dad..b2d93ac3 100644 --- a/source/src/python/nodes.cpp +++ b/source/src/python/nodes.cpp @@ -308,6 +308,9 @@ void init_python_nodes(py::module &m) .def(py::init(), "input"_a = 0.0, "filter_type"_a = SIGNALFLOW_FILTER_TYPE_LOW_PASS, "cutoff"_a = 440, "resonance"_a = 0.0, "peak_gain"_a = 0.0) .def(py::init(), "input"_a, "filter_type"_a, "cutoff"_a = 440, "resonance"_a = 0.0, "peak_gain"_a = 0.0); + py::class_>(m, "DCFilter", "Remove DC offset.") + .def(py::init(), "input"_a = 0.0); + py::class_>(m, "EQ", "Three-band EQ.") .def(py::init(), "input"_a = 0.0, "low_gain"_a = 1.0, "mid_gain"_a = 1.0, "high_gain"_a = 1.0, "low_freq"_a = 500, "high_freq"_a = 5000);