Digital Filter Designer: IIR & FIR Filters, C Code avatar

Digital Filter Designer: IIR & FIR Filters, C Code

Pricing

Pay per event

Go to Apify Store
Digital Filter Designer: IIR & FIR Filters, C Code

Digital Filter Designer: IIR & FIR Filters, C Code

Design lowpass, highpass, bandpass, bandstop and notch filters from plain text: Butterworth, Chebyshev, elliptic, Bessel or FIR (window, Kaiser, Parks-McClellan). Coefficients, measured response and C/Python/MATLAB code. For AI agents.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Jumble Mog

Jumble Mog

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Security

Limited permissions

Share

Design a digital filter by describing it. Type lowpass 100 Hz, fs 1 kHz, 4th order Butterworth or FIR lowpass 5 kHz, fs 48 kHz, 0.5 dB ripple, 60 dB down at 6 kHz, equiripple. You get back:

  • The coefficients: second-order sections (the stable way to run an IIR filter), b and a, zeros, poles and gain, or the FIR taps.
  • Ready-to-paste code in C (a biquad cascade or an FIR with a circular buffer), Python (SciPy, whole recordings or block by block) and MATLAB/Octave.
  • The response as measured: -3 dB points, gain at the cutoff, passband ripple, stopband attenuation, group delay in samples and ms, linear phase, stability and the largest pole radius.
  • A chart: magnitude response with your specs drawn in, group delay, impulse response, and poles and zeros on the unit circle.

It also:

  • Finds the order or length for you: give the passband edge, the stopband edge, the ripple and the attenuation, and you get the lowest IIR order or the shortest FIR that meets them.
  • Checks fixed point: round the coefficients to 16 bits (or any width from 4 to 32) and see the Q format, the integers, and whether the filter still works.
  • Filters your data: pass a signal and get it back filtered, causally or with zero phase.

It's made for:

  • Embedded and firmware developers putting a filter on a microcontroller or DSP.
  • Audio, sensor, biomedical (ECG, EEG) and vibration engineers.
  • Students checking filter-design homework.
  • AI agents that need correct coefficients instead of guessed ones.

A 111-tap Parks-McClellan lowpass designed by this Actor for 48 kHz audio: the magnitude response meeting 0.5 dB of passband ripple and 60.7 dB of stopband attenuation from 6 kHz, a flat 1.15 ms group delay, the symmetric impulse response, and its zeros on the unit circle

What it does

Filters it designs

  • Bands: lowpass, highpass, bandpass, bandstop, notch and peak (resonator).
  • IIR families:
    • Butterworth (maximally flat).
    • Chebyshev I (passband ripple) and Chebyshev II (stopband ripple).
    • Elliptic (the sharpest for a given order).
    • Bessel (the flattest group delay).
  • FIR methods:
    • Windowed sinc, with Hamming, Hann, Blackman, Blackman-Harris, Nuttall, flat-top, Bartlett or rectangular windows.
    • Kaiser window, with the length and β found from the attenuation and the transition width.
    • Parks-McClellan equiripple, the shortest FIR for a given spec.
    • Least squares.
  • Notch and peak biquads, by Q or bandwidth.

Writing filters

Most specs fit in one line:

  • Sample rate: fs 1 kHz, sample rate 48000, sampled at 250 Hz, or a trailing at 8 kHz.
  • Order or length: 4th order, order 6, 101 taps.
  • Specs: 1 dB ripple, 60 dB attenuation, 40 dB down at 200 Hz, stopband 6 kHz, transition 1 kHz.
  • Family or method: Butterworth, Chebyshev, Chebyshev II, elliptic, Bessel, FIR, Kaiser, equiripple, Hamming.

Objects work too, with the same fields named. Without a sample rate, frequencies like lowpass 0.2 are read as fractions of the Nyquist frequency.

Finding the order

When you give the stopband edge (or a transition width) and the attenuation, the order or length is found for you:

  • IIR: the lowest order that keeps the passband within the ripple and the stopband the given number of dB down.
  • Kaiser FIR: the length and β from Kaiser's formula.
  • Equiripple and least-squares FIR: the shortest length that meets both specs. It starts from an estimate, checks the result, and lengthens it until both specs are met.

Fixed point

Add coefficientBits and the coefficients are rounded to signed fixed point. You get:

  • The Q format (for example Q1.14 for 16 bits) and the integer coefficients.
  • Whether the rounded filter is still stable.
  • How far the passband moved, and the stopband attenuation that's left.

The chart overlays the rounded response.

Filtering a signal

Add signal (a list of numbers) and the filtered signal comes back. Set zeroPhase to filter forward and backward, with no delay. Up to 1,000,000 samples. Results over 10,000 samples come as a CSV file.

How to use it

  1. Write Filters, one per line, such as highpass 0.5 Hz, fs 250 Hz, 2nd order Butterworth. The form has examples.
  2. Optionally set a Default sample rate or Fixed-point coefficient bits for all of them.
  3. Click Start. Each filter is a row in the results, with its summary, chart, code and report.

Examples

All of these ran on this Actor, and the numbers are from the results.

FilterResult
lowpass 100 Hz, fs 1 kHz, 4th order Butterworth-3 dB at 99.94 Hz (the same sections as SciPy's butter), group delay 4.02-6.53 ms in the passband, stable
lowpass 100 Hz, fs 1 kHz, 0.5 dB ripple, 40 dB down at 200 HzOrder 8 Butterworth: 0.498 dB ripple, 46.8 dB at 200 Hz, -3 dB at 112.9 Hz
bandpass 300-3400 Hz, fs 8 kHz, 1 dB ripple, 40 dB down at 200 Hz and 3.8 kHz, elliptic + 16 bitsOrder 8 (4 per edge): 1 dB ripple, 40 dB stopband. In Q1.14 it's still stable and the passband moves by 0.006 dB
FIR lowpass 5 kHz, fs 48 kHz, 0.5 dB ripple, 60 dB down at 6 kHz, equiripple111 taps (109 fall short): 0.472 dB ripple, 60.7 dB stopband, linear phase, 55 samples (1.15 ms) of delay
FIR lowpass 5 kHz, fs 48 kHz, transition 1 kHz, 60 dB attenuation, kaiser176 taps, β 5.65: 59.7 dB stopband, 0.015 dB ripple
lowpass 1 kHz, fs 44.1 kHz, 60 dB down at 2 kHz, Chebyshev IIOrder 7: 0.98 dB ripple, 60 dB stopband, -3 dB at 1.081 kHz
notch 50 Hz, Q 20, fs 1 kHzA full null at 50 Hz, -3 dB at 48.76 and 51.27 Hz

The tests check that:

  • The designs match SciPy.
  • The automatic orders are the lowest that meet the specs, and the equiripple length is the shortest.
  • A notch's -3 dB width equals f₀/Q.
  • The generated C code, compiled with a C compiler, gives the same output as SciPy for a cascade of biquads and for an FIR.

How-to examples

Each example is a complete input; the results are from runs of the Actor (also listed under Examples).

How to design a Butterworth low-pass filter

{"filters": ["lowpass 100 Hz, fs 1 kHz, 4th order Butterworth"]}

Result: -3 dB at 99.94 Hz, the same sections as SciPy's butter, a group delay of 4.02-6.53 ms in the passband, and stable. You get the second-order sections, a frequency response chart and ready-to-paste C, Python and MATLAB code.

How to find the filter order that meets a spec

{"filters": ["lowpass 100 Hz, fs 1 kHz, 0.5 dB ripple, 40 dB down at 200 Hz", "FIR lowpass 5 kHz, fs 48 kHz, 0.5 dB ripple, 60 dB down at 6 kHz, equiripple"]}

Result: an order 8 Butterworth with 0.498 dB ripple and 46.8 dB at 200 Hz; and a 111-tap equiripple FIR (109 taps fall short) with 0.472 dB ripple, 60.7 dB stopband and 55 samples (1.15 ms) of delay.

How to design a notch filter for 50 or 60 Hz hum

{"filters": ["notch 50 Hz, Q 20, fs 1 kHz"]}

Result: a full null at 50 Hz, with -3 dB points at 48.76 and 51.27 Hz.

How to let an AI agent design filters

Add this Actor to the Apify MCP server with https://mcp.apify.com/?tools=jumblemog/digital-filter-designer. The agent describes the filter in one line and gives the user measured coefficients and code that was compiled and tested, instead of writing filter math from memory.

FAQ

Which filter types are there? IIR Butterworth, Chebyshev I and II, elliptic and Bessel, FIR by window (Kaiser and others) and equiripple, and notch and peak filters, as low-pass, high-pass, band-pass and band-stop.

Can I get C code for a microcontroller? Yes: a biquad cascade or an FIR with a circular buffer. The tests compile it and check its output against SciPy.

Does it check fixed-point coefficients? Yes. Set coefficientBits (4 to 32) and it gives the Q format and integers, and says whether the filter still works.

Can it filter my data? Yes. Pass a signal and get it back filtered, causally or with zero phase.

Does it work with Zapier, Make or n8n? Yes. Call the Actor with its Apify app or an HTTP request and pass the coefficients on.

Input

FieldWhat it is
filtersFilters, as text lines or objects (see below).
sampleRateDefault sample rate in Hz, for filters that don't give one.
coefficientBitsRound every filter to this many bits and check it.
chartsDraw charts (default on).

A filter as an object takes:

  • band, sampleRate, and cutoff (one frequency, or two for band filters).
  • type (iir or fir), family (butterworth, chebyshev1, chebyshev2, elliptic, bessel), method (window, kaiser, equiripple, least-squares) and window.
  • order or taps.
  • ripple and attenuation in dB, and stopband (edge frequencies) or transition (width).
  • q or bandwidth, for notch and peak filters.
  • coefficientBits, signal, zeroPhase and title.
  • text: a line of text to start from, which the other fields override.

Frequencies can be numbers in Hz or text like "1.5 kHz".

Output

One dataset item per filter, also saved together in the run's OUTPUT record:

{
"request": 1,
"status": "ok",
"title": "4th-order Butterworth lowpass at 100 Hz",
"summary": "4th-order Butterworth lowpass at 100 Hz (fs 1 kHz): -3 dB at 99.94 Hz, group delay 4.02-6.53 ms in the passband, stable.",
"band": "lowpass", "filterType": "iir", "design": "Butterworth, order 4", "sampleRate": 1000, "cutoff": [100], "order": 4,
"coefficients": {
"sos": [[0.0048243433577162282, 0.0096486867154324564, 0.0048243433577162282, 1, -1.0485995763626117, 0.29614035756166962],
[1, 2, 1, 1, -1.3209134308194264, 0.63273879288527657]],
"b": ["..."], "a": ["..."], "zeros": ["..."], "poles": [{"real": 0.6605, "imag": 0.4433, "radius": 0.7954}, "..."], "gain": 0.00482
},
"response": {"gainAtCutoffDb": [-3.0103], "minus3dB": [99.9445], "passbandRippleDb": null, "stopbandAttenuationDb": null,
"groupDelayMs": {"min": 4.02, "max": 6.53}, "linearPhase": false, "stable": true, "poleRadius": 0.795,
"points": [{"f": 0, "db": 0}, "..."]},
"impulseResponse": [0.00482, 0.0307, 0.0906, "..."],
"code": {"c": "/* Butterworth, order 4 ... */ ...", "python": "...", "matlab": "..."},
"imageUrl": "https://api.apify.com/v2/key-value-stores/.../records/001-....png",
"markdownUrl": "https://api.apify.com/v2/key-value-stores/.../records/001-....md"
}

Some results add more:

  • With coefficientBits: quantized holds format, scale, integers, stable, maxPassbandChangeDb and stopbandAttenuationDb.
  • With signal: filtered holds output and csvUrl.
  • Every result has warnings (instability, poles very close to the unit circle, specs not met, fixed-point damage) and notes (the order found, defaults used).

A filter that can't be designed has "status": "failed" and the reason in error, and isn't billed.

How it works

  1. The text is split into its parts: frequencies by their units, the sample rate by its label, and orders, taps, dB levels and family names by their words.
  2. IIR filters are designed in second-order sections with SciPy (butter, cheby1, cheby2, ellip, bessel). The order comes from buttord, cheb1ord, cheb2ord or ellipord. Notches and peaks come from iirnotch and iirpeak.
  3. FIR filters come from firwin (with kaiserord for Kaiser), remez or firls. Equiripple weights come from the ripple and the attenuation.
  4. Every filter is then measured on an 8,192-point grid, with the exact gain at the cutoff. Group delay is added up section by section.
  5. Charts are drawn with Vega-Lite and rendered with vl-convert.

Pricing

You pay one low price per filter designed, at the price shown on this page. It includes the code, the chart, the report, the fixed-point check and the filtered signal. Filters that can't be designed are never charged. If you set a maximum cost per run, the Actor stops before a filter that wouldn't fit.

Speed

A filter takes a few hundredths of a second plus its chart. A run through the API answers in about 5 to 10 seconds, including the cloud container starting.

Tips and limits

  • Use second-order sections for IIR filters above order 2 or so. The single b/a polynomial loses precision, and the result warns when the poles sit very close to the unit circle. The C code switches to double precision there.
  • Butterworth and Bessel cutoffs are their -3 dB points. A windowed FIR cutoff is its -6 dB point. Give a stopband edge to design to the passband edge instead.
  • Chebyshev II with an order and no stopband: the frequency you give is where the stopband begins.
  • Highpass and bandstop FIRs need an odd number of taps; an even count is raised by one.
  • Limits: IIR order up to 40, FIR up to 20,001 taps (8,001 when the length is found for you), 500 filters per run, signals up to 1,000,000 samples.

For AI agents and developers

This Actor works with the Apify MCP server, so AI agents can call it as a tool. Pass filters as plain text and read summary, coefficients.sos (or coefficients.b) and code from the result. A direct API call that waits for the answer:

curl -X POST "https://api.apify.com/v2/acts/jumblemog~digital-filter-designer/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"filters": ["highpass 0.5 Hz, fs 250 Hz, 2nd order Butterworth", "notch 60 Hz, Q 30, fs 250 Hz"]}'

run-sync instead returns the run's OUTPUT: the status, the counts and every result as JSON.

In Python, with the apify-client package:

from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("jumblemog/digital-filter-designer").call(run_input={
"filters": [{"band": "bandpass", "cutoff": ["0.5 Hz", "40 Hz"], "sampleRate": 500, "family": "butterworth",
"order": 4, "coefficientBits": 16}],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["summary"])
print(item["code"]["c"])

Credits

  • Filter design and analysis: SciPy scipy.signal (BSD-3-Clause).
  • Charts: Vega-Lite and vl-convert (BSD-3-Clause), with the Inter font (SIL Open Font License).
  • Methods:
    • McClellan, J. H., Parks, T. W. and Rabiner, L. R. (1973), A computer program for designing optimum FIR linear phase digital filters, IEEE Trans. Audio Electroacoustics 21(6), 506-526.
    • Kaiser, J. F. (1974), Nonrecursive digital filter design using the I₀-sinh window function, Proc. IEEE ISCAS.
    • Oppenheim, A. V. and Schafer, R. W., Discrete-Time Signal Processing, 3rd ed., Pearson.