Skip to main content

Dead-simple, ultra-fast signal processing in C

Project description

doppler

Dead-simple, ultra-fast, digital signal processing.

doppler is a lean C99 signal processing library built for one goal: maximum throughput with minimum friction — from any language. The full DSP stack lives in one portable core with paper-thin Python bindings and a Rust FFI. No runtime surprises, no framework lock-in.

What's inside

  • NCO — 32-bit phase accumulator, 2¹⁶-entry LUT, AVX-512 batch generation, FM ctrl port
  • FIR filter — AVX-512 complex taps, CI8/CI16/CI32/CF32 input types
  • FFT — 1D and 2D, selectable backend (FFTW or pocketfft)
  • SIMD arithmetic — SSE2/AVX2 complex multiply via dp_c16_mul
  • Signal streaming — low-latency ZMQ transport (PUB/SUB, PUSH/PULL, REQ/REP)
  • Circular buffers — double-mapped ring buffers for zero-copy, lock-free IPC (F32/F64/I16)
  • Multi-language — clean C ABI; Python bindings (NCO, FFT, streaming, buffers) and Rust FFI

Benchmarks

Measured on AMD Ryzen AI 7 350, Release build (-O3 -march=native). Re-run any suite with make blazing then the binary listed below.

NCO (dp_nco_*)

block=1 048 576 samples × 200 iterations./build/c/bench_nco_c

Rank Variant MSa/s Notes
🥇 u32 20 341 Raw phase only — store + add, no LUT
🥈 u32_ovf 3 028 Raw phase + carry bit (ADD + SETB)
🥉 cf32 2 094 Free-running IQ — AVX-512 16-wide gather
4 u32_ovf_ctrl 1 424 FM ctrl + raw phase + carry
5 u32_ctrl 1 095 FM ctrl + raw phase
6 cf32_ctrl 525 FM ctrl + IQ — LUT + ctrl overhead

FIR (dp_fir_execute_*)

taps=19 block=409 600 samples × 100 iterations./build/c/bench_fir_c

Input type MSa/s Notes
CI8 317 8-bit complex integer input
CF32 280 32-bit complex float input
CI16 235 16-bit complex integer input

FFT (dp_fft*)

FFTW backend, estimate plan, 1 thread, complex double — ./build/c/bench_fft_c

1D (fft1d_execute / fft1d_execute_inplace)

Size Out-of-place MSa/s In-place MSa/s
1 024 925 757
4 096 474 379
16 384 146 139

2D (fft2d_execute / fft2d_execute_inplace)

Size Out-of-place MSa/s In-place MSa/s
64 × 64 722 616
128 × 128 252 241
256 × 256 33 30

Ring buffer (dp_f32 / dp_f64)

Lock-free SPSC, 268 M samples, batch=4096 — ./build/c/bench_buffer_c

Type MSa/s GB/s
f32 (8 B/sample) 5 129 38.2
f64 (16 B/sample) 2 401 35.8

Quick example

C:

#include <doppler.h>
#include <dp/fft.h>
#include <complex.h>

size_t shape[] = {1024};
dp_fft_global_setup(shape, 1, -1, 1, "estimate", NULL);

double complex in[1024], out[1024];
/* ... fill in[] ... */
dp_fft1d_execute(in, out);

Python:

from doppler.fft import fft
import numpy as np

x = np.random.randn(1024) + 1j * np.random.randn(1024)
spectrum = fft(x)

Documentation

Document Contents
Quick Start Build, install, run the examples (Docker quickstart included)
Build Guide CMake options, platform notes, Python setup, Docker details
Overview Architecture and full API reference
Examples C and Python code examples - FFT, SIMD, streaming

| CLAUDE.md | Development notes and project context (for contributors) |

Build

make          # build (Linux/macOS; MSYS2 on Windows)
make test     # run CTest suite

Or with Python bindings:

make && uv sync

See Build Guide for platform-specific instructions and all CMake options.

Licensing

The doppler source code is MIT-licensed.

If built with FFTW support (default), the resulting binary links against FFTW, which is licensed under the GNU General Public License (GPL). In this case, the distributed binary is covered by the GPL.

If built with -DUSE_FFTW=OFF, the pocketfft backend is used instead. pocketfft is BSD-3-Clause-licensed (see POCKETFFT_LICENSE) which is compatible with the MIT-license and so the resulting binary remains MIT-licensed with BSD-3-Clause licensed FFT features.

See Build Guide for details and the installed LICENSE files.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

doppler_dsp-0.2.0.tar.gz (34.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

doppler_dsp-0.2.0-py3-none-any.whl (43.7 kB view details)

Uploaded Python 3

File details

Details for the file doppler_dsp-0.2.0.tar.gz.

File metadata

  • Download URL: doppler_dsp-0.2.0.tar.gz
  • Upload date:
  • Size: 34.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for doppler_dsp-0.2.0.tar.gz
Algorithm Hash digest
SHA256 4c61092ea450dc9fca9207b7c216db4ac9741b68c39d4ebb17b360003af82d2e
MD5 57bd6c9768c0c0c320ba1e6f9f9ac83a
BLAKE2b-256 6f3eaf1c89ef2964cac03eedba353d0ed4beab7e423858a0c2a3d4fbf5a46d19

See more details on using hashes here.

Provenance

The following attestation bundles were made for doppler_dsp-0.2.0.tar.gz:

Publisher: release.yml on doppler-dsp/doppler

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file doppler_dsp-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: doppler_dsp-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 43.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for doppler_dsp-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ab9b8ad54776c1fad4bac54185a023b830dd390be7fb51b9048da53b3ea72449
MD5 337118e77740d231dee9fc3364a9d297
BLAKE2b-256 84cfe83b58b4600353001982e20d52149515a9e7c659bfd17c8eacaf99fd0f20

See more details on using hashes here.

Provenance

The following attestation bundles were made for doppler_dsp-0.2.0-py3-none-any.whl:

Publisher: release.yml on doppler-dsp/doppler

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page