related to digital signal processing
digital filters are tools used to attenuate or remove frequencies or change phase relationships between frequencies. it is an effect on the amplitude of frequency partials.
windowed sinc
state-variable filter
one-pole, one-zero, multi-pole
moving average
con: almost useless for removing frequencies because it filters with large ripples in the frequency spectrum
pro: good for smoothing and anywhere where time domain shape matters more than frequencies. a centered moving average creates no shift between input and output signal
moving median and similar also possible
x: input, y: output, alpha: cutoff as fraction of the sample rate
high-pass
for i from 1 to n y[i] := alpha * (y[i-1] + x[i] - x[i-1])
low-pass
for i from 1 to n y[i] := y[i-1] + alpha * (x[i] - y[i-1])
based on the state-variable filter described here:
#include <math.h> #include <inttypes.h> void state_variable_filter(double* out, double* in, double in_count, double cutoff, double q_factor, double* state) { double a1; double a2; double g; double ic1eq; double ic2eq; uint32_t i; double k; double v0; double v1; double v2; ic1eq = state[0]; ic2eq = state[1]; g = tan(M_PI * cutoff); k = 2 - 2 * q_factor; a1 = 1 / (1 + g * (g + k)); a2 = g * a1; for (i = 0; i < in_count; i = (1 + i)) { v0 = in[i]; v1 = a1 * ic1eq + a2 * (v0 - ic2eq); v2 = ic2eq + (g * v1); ic1eq = 2 * v1 - ic1eq; ic2eq = 2 * v2 - ic2eq; // low-pass out[i] = v2; // instead of the low-pass result, other results could be written to out, // or multiple results if multiple output arrays are made available // high-pass //out[i] = v0 - k * v - v2; // band-pass //out[i] = v1; // band-reject //out[i] = v0 - k * v1; // peak //out[i] = 2 * v2 - v0 + k * v1; // all-pass //out[i] = v0 - 2 * k * v1; }; state[0] = ic1eq; state[1] = ic2eq; }