Also known as: csdr
csdr is a command-line digital-signal-processing toolkit in which each DSP operation is a small program that reads samples from standard input and writes them to standard output, so a complete SDR signal chain is built by connecting the programs with Unix pipes.1 It is best known as the DSP engine inside OpenWebRX, where csdr commands turn raw IQ into demodulated audio on the server.
How it works
csdr embraces the Unix philosophy: instead of one monolithic application, it provides many tiny
tools — fir_decimate_cc, shift_addition_cc, fmdemod_quadri_cf, agc_ff, bandpass_fir_fft_cc,
convert_u8_f, and dozens more — each doing one DSP job on a stream of raw samples. Samples cross
the pipes as headerless binary: complex float pairs for IQ (_cc/_cf suffixes) or real floats
for audio (_ff/_ff). A naming convention encodes each tool’s input and output type, so the
suffixes tell you what can legally connect to what. To demodulate a station you decimate to the
channel bandwidth, shift the channel to baseband, filter, demodulate, and resample to audio — each
step a separate process, all running concurrently while the OS schedules them and pipe buffers
provide flow control.
Under the hood the DSP is written in C for speed, with SIMD-optimized FIR filters and FFT routines. Later versions reorganized into a C++ library with a thin command wrapper, but the pipe-friendly command interface remained the defining feature.
Variants
Two lineages exist. The original ha7ilm/csdr by András Retzler established the tool set and
its use in the first OpenWebRX. The actively maintained jketterl/csdr fork, developed alongside
the modern OpenWebRX, refactored the internals into a reusable C++ library and a csdr command
front end, added modules, and improved performance while keeping the pipeline model. A companion
project, pycsdr, exposes the same DSP blocks to Python so chains can be built in code rather than
in a shell.
In practice
csdr’s natural habitat is server-side SDR streaming, above all OpenWebRX: when a browser client tunes a channel, the server assembles a csdr pipeline for the requested mode (AM, FM, SSB, digital), feeds it IQ from the receiver, and streams the resulting audio out. The pipe model makes it trivial to prototype and reconfigure a chain from the shell and to splice in other Unix tools. Its trade-offs are the trade-offs of processes and pipes: copying float streams between programs costs memory bandwidth, and very tight, low-latency loops are better served by an in-process library such as liquid-dsp.
Relevance to SDR
csdr is a compact demonstration that a full receive chain — decimation, translation, filtering, demodulation, resampling — is just a sequence of stream transforms, and that Unix pipes are a perfectly good “flowgraph” for connecting them. That makes it an excellent teaching and scripting tool and the reason web-SDR platforms could offer many modes without a heavyweight framework.
GopherTrunk implements the same conceptual chain, but in-process rather than across pipes: its Go pipeline decimates, translates each channel to baseband with a downconverter, filters, and demodulates, passing sample buffers between stages inside one program. GT is a decoder of digital trunking rather than an analog audio streamer, and it favors a single statically compiled binary over a shell of cooperating processes — but csdr’s stage-by-stage view of the signal chain maps directly onto what GT does internally, and both rely on the same primitives, above all the FIR filter.
Sources
-
csdr repository — the maintained csdr DSP toolkit, documenting its command/pipe interface, sample-type conventions, and use inside OpenWebRX. ↩