This is a from-scratch digital filter designer: pick a real FIR or IIR filter, and every number on screen — the impulse response bars, the Bode magnitude/phase plot and the scrolling before/after trace — comes from actually running the filter's difference equation, not from a canned curve.
y[n] = (1/N) · Σ x[n-k], a simple always-stable low-pass.y[n] = Σ b[k]·x[n-k] − Σ a[k]·y[n-k], applied one sample at a time.
Difference equation: y[n] = Σ_{k=0}^{M} b[k]·x[n-k] − Σ_{k=1}^{N} a[k]·y[n-k].
Frequency response: H(e^jω) = Σ h[n]·e^(-jωn), the discrete Fourier
transform of the impulse response h[n], plotted as 20·log10|H| dB
magnitude and atan2(Im, Re) phase.
A plain moving-average filter is the crudest possible low-pass, yet it is exactly what many simple sensor-smoothing routines use. Real audio equalisers and speaker crossovers use the same RBJ biquad formulas computed here, and this simulator's Bode plot is calculated by literal brute-force DFT summation — the same idea behind the FFT, just without the speed shortcut.
A hands-on FIR/IIR filter designer that runs the real digital-signal-processing math in the open: a genuine sample-by-sample difference equation, an impulse response you can see as bars, and a Bode plot computed by literally summing the discrete Fourier transform of that response.
FIR filters (moving average, windowed-sinc) use only past inputs and are always stable; IIR biquad cascades add feedback from past outputs, reaching steeper roll-off with fewer coefficients but risking instability at extreme settings. The same direct-form-I equation drives the impulse response, the Bode plot and the live oscilloscope.
Pick a filter type, then drag Taps/Stages and Cutoff and watch the impulse-response bars and Bode magnitude/phase redraw instantly. Switch the test signal to Sine or Square and move Freq to slide a marker across the Bode plot while watching the oscilloscope track the real filtered waveform.
The brute-force DFT sum used for this Bode plot is exactly what the Fast Fourier Transform speeds up — the FFT computes the same numbers, just in O(N log N) instead of O(N²). A three-tap moving average is one of the oldest smoothing filters in engineering, dating back to hand-computed statistics long before digital computers existed.
This tool builds real FIR and IIR digital filters and runs them honestly: an FIR moving average or Hamming-windowed sinc, or an IIR cascade of RBJ-cookbook biquad low-pass/high-pass sections, all reduced to the same b[]/a[] coefficient pair. A single direct-form-I difference equation function processes every sample — the impulse response is that function fed a unit impulse, the Bode magnitude/phase plot is the literal discrete Fourier transform of that impulse response, and the oscilloscope streams a real test signal through the same live filter state one sample at a time.
Because every view is derived from the same coefficients and the same difference equation, moving a slider changes all three displays consistently: the impulse-response bars, the Bode curve, and the filtered waveform. This mirrors how real DSP toolchains validate a filter design — compute the coefficients once, then check impulse response, frequency response and time-domain behaviour all agree.
What is a difference equation?
A difference equation is the digital equivalent of a differential equation: it computes each output sample from a weighted sum of current and past input samples, and for feedback (IIR) filters, past output samples too. This simulator implements it directly as y[n] = Σ b[k]·x[n-k] − Σ a[k]·y[n-k].
What is the difference between the FIR and IIR filters here?
FIR Moving Average and FIR Windowed-Sinc use only feedforward taps (a = [1]), so they are always stable. IIR Low-pass and High-pass cascade second-order biquad sections with feedback, reaching a comparable roll-off with far fewer coefficients but needing their poles to stay inside the unit circle for stability.
How is the Bode plot actually computed?
The simulator first computes the filter's impulse response by feeding a unit impulse through the exact same difference equation used for live filtering. It then evaluates the discrete Fourier transform of that impulse response directly, by summing h[n]·e^(-jωn) at each frequency point, and converts the result to magnitude in decibels and phase in degrees.
What do the controls do?
The four buttons pick the filter design. Taps/Stages sets the FIR tap count or the number of cascaded IIR biquad sections (1–4). Cutoff sets the transition frequency in Hz (unused by the plain moving average). The signal buttons choose what is streamed through the live filter, and Freq sets the sine/square test frequency.
A boxcar moving average has no explicit cutoff parameter — its frequency response is entirely determined by how many samples it averages (its tap count). Averaging more samples pushes its first null lower in frequency, acting like a lower cutoff, so Taps is the only control it needs.
An ideal low-pass filter's impulse response is an infinite sinc function. Truncating it abruptly to a finite number of taps causes ripple (Gibbs phenomenon). Multiplying by a Hamming window (0.54 − 0.46·cos) tapers the ends smoothly, trading a slightly wider transition band for much lower ripple.
They are the widely used "Audio EQ Cookbook" bilinear-transform formulas (by Robert Bristow-Johnson) that turn a cutoff frequency and Q factor into a stable second-order digital filter section. This simulator uses a fixed Q of 1/√2 (a Butterworth-style maximally flat response) per cascaded stage.
Each cascaded biquad section multiplies the transfer function by another second-order factor, so stacking sections steepens the roll-off and pushes stopband attenuation lower, at the cost of accumulating more feedback and needing better numerical care to stay stable.
It is live. Every frame, a fixed time-accumulator advances a nominal 800 Hz sample clock, generates the next real test-signal sample, and pushes it through the same difference-equation state used to build the impulse response — the scrolling trace is that computation's actual output, decimated only for a readable scroll speed.
The 3D version adds a pole-zero Z-plane diagram (found with a polynomial root solver), Butterworth and Chebyshev IIR designs, and renders everything through a WebGL/Three.js pipeline. This 2D companion instead exposes the impulse response as bars and drives a continuously streaming oscilloscope, using a plain 2D canvas and a simpler moving-average/windowed-sinc/biquad filter set.