Announcing ThinkDSP.jl: a Julia toolkit for signals, spectra, and audio

I have always liked working with DSP in Python. Libraries such as the original Think DSP code make it easy to move from a signal, to a sampled wave, to a spectrum, apply a filter, and reconstruct the result without losing sight of the underlying ideas.
I wanted a similar workflow in Julia: concise and approachable for experimentation, while still being comfortable for larger numerical workloads. That became ThinkDSP.jl.
ThinkDSP.jl is an idiomatic Julia implementation inspired by Allen Downey’s Think DSP. It provides tools for working with signals, sampled waves, FFT spectra, DCTs, filters, spectrograms, WAV files, and MIDI-style notes and chords.
Repository: GitHub - Spidy104/ThinkDSP.jl · GitHub
A small example

using ThinkDSP

signal = Sinusoid(440.0)
wave = make_wave(signal; duration=1.0, framerate=44_100)
spec = spectrum(wave)
println("Peak frequency: ", spec.fs[argmax(magnitude(spec))], " Hz")

The API is intended to follow the natural DSP workflow:

spec = spectrum(wave)
filtered = lowpass(spec, 800.0)
output = wave(filtered)

Why Julia?
For me, Julia feels like a particularly nice fit for DSP work. It keeps the interactive, high-level workflow that makes Python enjoyable, while allowing direct access to multiple dispatch, type-generic numerical code, and performant array operations without needing to switch languages for the core implementation.
The goal is not to replace every excellent Julia DSP package. ThinkDSP.jl builds on packages such as DSP.jl, FFTW.jl, and WAV.jl, and aims to offer a coherent, educational, end-to-end interface for common signal-processing tasks.
Current features

  • Signal families: sinusoids, periodic signals, chirps, impulses, and colored noise
  • Wave operations for arithmetic, windows, segmentation, convolution, normalization, and more
  • FFT-based one-sided and full spectra
  • DCT and reusable FFTW-backed transform workspaces
  • Low-pass, high-pass, band-stop, pink-noise filters, differentiation, and integration
  • STFT spectrograms with normalized overlap-add reconstruction
  • WAV read/write and 8/16/24/32-bit PCM quantization
  • MIDI frequency conversion, note generation, chords, and rests
  • RecipesBase plotting support for Plots.jl and compatible frontends
  • Numerical validation, Python-reference comparisons, benchmarks, Aqua, and JET checks

The project currently targets Julia 1.12+ and is not registered yet. I would appreciate feedback on the API, naming, documentation, Julia package conventions, and anything that should be improved before the first release.

What is the main difference to GitHub - sz73/ThinkDSP.jl: Julia implementation of Allen Downey's Think DSP https://github.com/AllenDowney/ThinkDSP · GitHub ?

Thanks for sharing this @ufechner7, I had not seen sz73/ThinkDSP.jl (GitHub - sz73/ThinkDSP.jl: Julia implementation of Allen Downey's Think DSP https://github.com/AllenDowney/ThinkDSP · GitHub) before.

We are both inspired by Allen Downey’s original Think DSP project, but the two Julia implementations have grown in somewhat different directions.
sz73/ThinkDSP.jl has a compact API centered around Signal, Wave, and Spectrum, with plotting, signal mixing, and several noise types. It looks like a nice direct and approachable interpretation of the material.
My project, Spidy104/ThinkDSP.jl (GitHub - Spidy104/ThinkDSP.jl · GitHub), is more of a learning project for me while I build more things in Julia and share them with the community. I took a broader, more experimental direction:

  • Separate signal families, sampled waves, FFT spectra, DCTs, and spectrograms
  • FFT/DCT/spectrogram workspaces for repeated transforms
  • Filters, spectral differentiation/integration, convolution, and windowing
  • STFT reconstruction with normalized overlap-add
  • WAV read/write, PCM quantization, MIDI notes, chords, and rests
  • Numerical validation, reference comparisons, benchmarks, and package-quality checks

The APIs are not drop-in compatible, and I would not present mine as a replacement for the earlier project. It is simply another attempt at bringing the Think DSP style of exploration to Julia, while also being a place for me to learn package design, testing, documentation, and numerical programming.
I am definitely not a salesman for my own project, and it is not registered or presented as production-ready yet. But if anyone is interested in this corner of Julia DSP, I think both projects are worth taking for a test drive. Feedback, comparisons, and criticism are all welcome. Pardon me I still can’t get back the formatting to work pardon me for that…