Fork me on GitHub

Signal processing, in pure Go.
Designed like SciPy, checked against its answers.

go-dsp is the signal-processing layer of the Go scientific stack: filter design and filtering, spectral estimation and resampling, with the semantics of SciPy's scipy.signal. Its tests replay recorded SciPy answers, its documentation lists the error of every group of values in ULPs, and it says where it is slower. No cgo.

225 groups of values measured in ULPs100% statement coverage28 speed cases against SciPy
main.go
import "github.com/go-dsp/signal"

z, _ := signal.Butter(8, []float64{0.2}, signal.Lowpass, nil) // zeros, poles, gain
sos, _ := z.SOS(false)                                        // second-order sections
y, _ := signal.SOSFiltFilt(sos, x, nil)                       // zero-phase filtering
f, p, _ := signal.Welch(x, &signal.SpectralOptions{Fs: 1000, Nperseg: 1024})
3 repositories — one library: go get github.com/go-dsp/signal
Why go-dsp

The scipy.signal calls, in Go.

Each function names the SciPy call it corresponds to and, where it differs, a note on MATLAB's. Option structs have useful zero values, and nothing panics on bad arguments: functions that can fail return an error.

〰️

IIR design

Butterworth, Chebyshev types 1 and 2, elliptic and Bessel filters, order selection, notch and peak filters, as zeros-poles-gain, transfer function or second-order sections.

🎚️

FIR design and windows

Window method, frequency-sampling, Parks–McClellan Remez, least squares, Kaiser order estimation, and more than twenty windows including Chebyshev and DPSS.

🔁

Filtering

LFilter, SOSFilt and their zero-phase forms FiltFilt and SOSFiltFilt, with initial conditions; convolution, correlation and overlap-add.

📊

Spectral estimation

Periodogram, Welch, cross-spectrum, coherence, spectrogram, STFT and its inverse, and Lomb–Scargle for unevenly sampled data.

⏩

Resampling

FFT and polyphase resampling, decimation and Upfirdn; the analytic signal with Hilbert; detrending.

⛰️

Peak finding

FindPeaks with height, threshold, distance, prominence, width and plateau conditions, and the prominence and width functions behind it.

📦

Pure Go, CGO=0

No cgo. The FIR kernels call the SIMD dot product of go-simd/floats; the transforms come from go-fft.

⚖️

BSD-3-Clause

Every repository of the organization. Ported code keeps its attribution in place.

What is checked

4 kinds of check, each against a recorded answer.

The fixtures are SciPy's own output, recorded once and replayed. What differs, and why, is in the library's documentation.

SciPy 1.18.1 as the oracle

Every comparison is recorded from SciPy 1.18.1 with NumPy 2.5.4 and replayed from testdata/oracle, so go test needs no Python and the same recorded output is checked on every architecture CI runs. (signal)

Errors in ULPs, 225 groups

docs/accuracy.md lists the maximum ULP error, the normwise relative error and the exact-equality count for 225 groups of values, and docs/verification.md names the few places where SciPy itself is the less accurate side. (signal)

Covered, raced and fuzzed

100% statement coverage with -race, error paths included; fuzz targets for the design constructors, the spectral estimators, the convolutions and the peak finder; gofmt, go vet and govulncheck. (signal)

Architectures

Tests on amd64, arm64 and 386, under qemu on riscv64, loong64, ppc64le, s390x and arm, and every GOOS/GOARCH pair compiling the tests. (signal)

Speed

Measured against SciPy, on one core.

Best of 5 interleaved rounds on one core (the SciPy process runs with its threads set to 1), on a 16-CPU darwin/arm64 host, with SciPy 1.18.1, measured 2026-10-19 and recorded in the library's docs/perf.md. In the 28 cases measured, no row is slower than SciPy; the closest are within 2%.

casego-dspSciPy 1.18.1SciPy / Go
welch, 10⁶ samples, nperseg 256 (signal)8.42 ms86.92 ms10×
welch, 10⁶ samples, nperseg 1024 (signal)7.83 ms30.74 ms3.9×
sosfilt, 10⁶ samples, order 8 (signal)4.63 ms7.20 ms1.6×
sosfiltfilt, 10⁶ samples, order 8 (signal)10.40 ms14.94 ms1.4×
fftconvolve, 10⁶ × 10⁴ (signal)10.47 ms19.78 ms1.9×
resample_poly 1/4, 10⁶ samples (signal)6.59 ms15.35 ms2.3×
remez, 501 taps (signal)1.17 ms6.54 ms5.6×
find_peaks with prominence, 10⁶ samples (signal)17.12 ms18.96 s1100×
butter order 8, zpk to sos (signal)2.3 µs282.7 µs120×
lfilter FIR, 101 taps, 10⁶ samples (signal)14.53 ms14.78 ms1.02×
Repositories

What is here.

signal

released v0.1.0

Filter design (Butterworth, Chebyshev, elliptic, Bessel, window method, Parks–McClellan, least squares), windows, filtering and zero-phase filtering, convolution, Welch, STFT and Lomb–Scargle estimation, resampling and peak finding, with the semantics of scipy.signal.

docs

site

The documentation (Hugo + Hextra): the library's own README, verification, accuracy and performance documents. Source →

brand

assets

Logos and icons for the organization, in SVG / PNG / JPG / ICO / ICNS across colour, white and black variants.

Signal processing for the Go scientific stack.

go-dsp builds on go-fft for transforms and windows, go-numerics for special functions and go-simd for its dot-product kernels. Wavelets and audio I/O are planned in this organization and not started; what signal does not provide is listed in the documentation.

Read the source on GitHub →