sdr: A software defined radio library

[ bsd3, software-defined-radio ] [ Propose Tags ]

Write software defined radio applications in Haskell.


See for more features and screenshots.

A collection of simple apps that use this library can be found here. These include an FM radio receiver, an OpenGL waterfall plotter and an AM radio receiver.

[Skip to Readme]
Dependencies array (>=0.4 && <0.6), base (>=4.6 && <4.9), bytestring (==0.10.*), cairo (==0.13.*), cereal (==0.4.*), Chart (>=1.3 && <1.5), Chart-cairo (>=1.3 && <1.5), colour (==2.3.*), containers (==0.5.*), Decimal (==0.4.*), dynamic-graph (==, either (>=4.1 && <4.4), fftwRaw (==0.1.*), GLFW-b (==1.4.7.*), OpenGL (>=2.11 && <2.13), optparse-applicative (==0.11.*), pango (==0.13.*), pipes (==4.1.*), pipes-bytestring (>=2.0 && <2.2), pipes-concurrency (==2.0.*), primitive (>=0.5 && <0.7), pulse-simple (==0.1.*), rtlsdr (==0.1.*), storable-complex (==0.2.*), time (>=1.4 && <1.6), tuple (>=0.2 && <0.4), vector (==0.10.*) [details]
License BSD-3-Clause
Copyright 2015 Adam Walker
Author Adam Walker
Category Software Defined Radio
Home page
Bug tracker
Source repo head: git clone
Uploaded by adamwalker at Sun May 10 05:19:08 UTC 2015
Distributions NixOS:
Downloads 1989 total (42 in the last 30 days)
Rating (no votes yet) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]
Hackage Matrix CI




Maintainer's Corner

For package maintainers and hackage trustees

Readme for sdr-

[back to package description]


A Software Defined Radio library written in Haskell


  • Write software defined radio applications in Haskell
  • Signal processing blocks can be chained together using the Pipes library
  • Zero copy design
  • Signal processing functions are implemented in both Haskell and C:
    • Optimised C implementations of signal processing functions that utilise SIMD instructions
    • Performance of Haskell signal processing functions within a factor of 2 of C (without SIMD) thanks to the vector library, stream fusion and ghc's LLVM backend
  • Can filter, decimate and resample
  • Helper functions for FIR filter design using window functions and plotting of the frequency response
  • FFTs using FFTW
  • Line and waterfall plots using OpenGL
  • FM demodulation
  • PulseAudio sound sink
  • rtl-sdr based radio source supported and other sources are easily added
  • Extensive benchmark and test suites of signal processing functions

See for a collection of simple apps built on the library and for a demo application.


A chunk of the FM broadcast spectrum. Captured with an RTLSDR device and drawn as a waterfall using the Plot module.


Getting Started


Building with cabal sandboxes is recommended:

cabal sandbox init
git clone
git clone
git clone
cabal sandbox add-source dynamic-graph haskell-fftw-simple sdr
cabal install sdr

Example Applications

A collection of simple apps can be found here. These include an FM radio receiver, an OpenGL waterfall plotter and an AM radio receiver that can be used to listen to Airband.

Clone and build:

git clone  
cabal sandbox add-source sdr-apps
cabal install sdr-apps

To run the FM receiver:

.cabal-sandbox/bin/fm -f <your favourite station, e.g. 90.2M>  

To run the waterfall plot:

.cabal-sandbox/bin/waterfall -f <center frequency, e.g. 90.2M> -r <sample rate, e.g. 1280M>

To run the AM receiver:

.cabal-sandbox/bin/am -f <center frequency, e.g. 124.4M> 


An FM receiver:

import           Control.Monad.Trans.Either
import           Data.Vector.Generic        as VG 
import           Pipes
import qualified Pipes.Prelude              as P
import           Foreign.Storable.Complex

import SDR.Filter 
import SDR.RTLSDRStream
import SDR.Util
import SDR.Demod
import SDR.Pulse
import SDR.CPUID

--The filter coefficients are stored in another module
import Coeffs

samples    = 8192
frequency  = 105700000

main = eitherT putStrLn return $ do

    info <- lift getCPUInfo

    str  <- sdrStream frequency 1280000 1 (fromIntegral samples * 2)

    lift $ do

        sink <- pulseAudioSink

        deci <- fastDecimatorC info 8 coeffsRFDecim 
        resp <- fastResamplerR info 3 10 coeffsAudioResampler
        filt <- fastFilterSymR info coeffsAudioFilter

        runEffect $   str
                  >-> convertCAVX 
                  >-> firDecimator deci samples 
                  >-> fmDemod
                  >-> firResampler resp samples 
                  >-> firFilter filt samples
                  >-> ( (* 0.2)) 
                  >-> sink


I started this project to learn about signal processing. I still have no idea what I'm doing.

Only tested on Arch Linux.

If you actually use this library for anything, let me know: