about summary refs log tree commit diff
path: root/nixpkgs/pkgs/applications/radio
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/applications/radio')
-rw-r--r--nixpkgs/pkgs/applications/radio/airspy/default.nix33
-rw-r--r--nixpkgs/pkgs/applications/radio/aldo/default.nix21
-rw-r--r--nixpkgs/pkgs/applications/radio/chirp/default.nix24
-rw-r--r--nixpkgs/pkgs/applications/radio/cubicsdr/default.nix30
-rw-r--r--nixpkgs/pkgs/applications/radio/dablin/default.nix28
-rw-r--r--nixpkgs/pkgs/applications/radio/dabtools/default.nix27
-rw-r--r--nixpkgs/pkgs/applications/radio/dmrconfig/default.nix42
-rw-r--r--nixpkgs/pkgs/applications/radio/dump1090/default.nix43
-rw-r--r--nixpkgs/pkgs/applications/radio/ebook2cw/configfile.patch11
-rw-r--r--nixpkgs/pkgs/applications/radio/ebook2cw/default.nix25
-rw-r--r--nixpkgs/pkgs/applications/radio/fldigi/default.nix23
-rw-r--r--nixpkgs/pkgs/applications/radio/fllog/default.nix33
-rw-r--r--nixpkgs/pkgs/applications/radio/flmsg/default.nix33
-rw-r--r--nixpkgs/pkgs/applications/radio/flrig/default.nix33
-rw-r--r--nixpkgs/pkgs/applications/radio/flwrap/default.nix33
-rw-r--r--nixpkgs/pkgs/applications/radio/gnss-sdr/default.nix80
-rw-r--r--nixpkgs/pkgs/applications/radio/gnuradio/ais.nix40
-rw-r--r--nixpkgs/pkgs/applications/radio/gnuradio/default.nix165
-rw-r--r--nixpkgs/pkgs/applications/radio/gnuradio/gsm.nix39
-rw-r--r--nixpkgs/pkgs/applications/radio/gnuradio/limesdr.nix40
-rw-r--r--nixpkgs/pkgs/applications/radio/gnuradio/nacl.nix39
-rw-r--r--nixpkgs/pkgs/applications/radio/gnuradio/osmosdr.nix47
-rw-r--r--nixpkgs/pkgs/applications/radio/gnuradio/rds.nix38
-rw-r--r--nixpkgs/pkgs/applications/radio/gnuradio/wrapper.nix24
-rw-r--r--nixpkgs/pkgs/applications/radio/gqrx/default.nix48
-rw-r--r--nixpkgs/pkgs/applications/radio/hackrf/default.nix37
-rw-r--r--nixpkgs/pkgs/applications/radio/inspectrum/default.nix40
-rw-r--r--nixpkgs/pkgs/applications/radio/kalibrate-hackrf/default.nix37
-rw-r--r--nixpkgs/pkgs/applications/radio/kalibrate-rtl/default.nix31
-rw-r--r--nixpkgs/pkgs/applications/radio/limesuite/default.nix48
-rw-r--r--nixpkgs/pkgs/applications/radio/minimodem/default.nix41
-rw-r--r--nixpkgs/pkgs/applications/radio/multimon-ng/default.nix43
-rw-r--r--nixpkgs/pkgs/applications/radio/pyradio/default.nix24
-rw-r--r--nixpkgs/pkgs/applications/radio/qradiolink/default.nix60
-rw-r--r--nixpkgs/pkgs/applications/radio/qsstv/default.nix36
-rw-r--r--nixpkgs/pkgs/applications/radio/rtl-ais/default.nix24
-rw-r--r--nixpkgs/pkgs/applications/radio/rtl-sdr/default.nix37
-rw-r--r--nixpkgs/pkgs/applications/radio/rtl_433/default.nix29
-rw-r--r--nixpkgs/pkgs/applications/radio/sdrangel/default.nix76
-rw-r--r--nixpkgs/pkgs/applications/radio/soapyairspy/default.nix31
-rw-r--r--nixpkgs/pkgs/applications/radio/soapybladerf/default.nix32
-rw-r--r--nixpkgs/pkgs/applications/radio/soapyhackrf/default.nix31
-rw-r--r--nixpkgs/pkgs/applications/radio/soapyremote/default.nix29
-rw-r--r--nixpkgs/pkgs/applications/radio/soapyrtlsdr/default.nix31
-rw-r--r--nixpkgs/pkgs/applications/radio/soapysdr/default.nix55
-rw-r--r--nixpkgs/pkgs/applications/radio/soapyuhd/default.nix35
-rw-r--r--nixpkgs/pkgs/applications/radio/svxlink/default.nix71
-rw-r--r--nixpkgs/pkgs/applications/radio/tlf/default.nix40
-rw-r--r--nixpkgs/pkgs/applications/radio/tqsl/default.nix30
-rw-r--r--nixpkgs/pkgs/applications/radio/uhd/default.nix160
-rw-r--r--nixpkgs/pkgs/applications/radio/uhd/neon.patch19
-rw-r--r--nixpkgs/pkgs/applications/radio/unixcw/default.nix37
-rw-r--r--nixpkgs/pkgs/applications/radio/unixcw/remove-use-of-dlopen.patch677
-rw-r--r--nixpkgs/pkgs/applications/radio/urh/default.nix38
-rw-r--r--nixpkgs/pkgs/applications/radio/welle-io/default.nix51
-rw-r--r--nixpkgs/pkgs/applications/radio/wsjtx/default.nix44
-rw-r--r--nixpkgs/pkgs/applications/radio/wsjtx/super.patch12
-rw-r--r--nixpkgs/pkgs/applications/radio/wsjtx/wsjtx.patch13
-rw-r--r--nixpkgs/pkgs/applications/radio/xlog/default.nix31
59 files changed, 3029 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/applications/radio/airspy/default.nix b/nixpkgs/pkgs/applications/radio/airspy/default.nix
new file mode 100644
index 000000000000..67a59b68cd5b
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/airspy/default.nix
@@ -0,0 +1,33 @@
+{ stdenv, lib, fetchFromGitHub
+, cmake , pkgconfig, libusb1
+}:
+
+stdenv.mkDerivation rec {
+  pname = "airspy";
+  version = "1.0.9";
+
+  src = fetchFromGitHub {
+    owner = "airspy";
+    repo = "airspyone_host";
+    rev = "v${version}";
+    sha256 = "04kx2p461sqd4q354n1a99zcabg9h29dwcnyhakykq8bpg3mgf1x";
+  };
+
+  postPatch = ''
+    substituteInPlace airspy-tools/CMakeLists.txt --replace "/etc/udev/rules.d" "$out/etc/udev/rules.d"
+  '';
+
+  nativeBuildInputs = [ cmake pkgconfig ];
+  buildInputs = [ libusb1 ];
+
+  cmakeFlags =
+    lib.optionals stdenv.isLinux [ "-DINSTALL_UDEV_RULES=ON" ];
+
+  meta = with stdenv.lib; {
+    homepage = "https://github.com/airspy/airspyone_host";
+    description = "Host tools and driver library for the AirSpy SDR";
+    license = licenses.bsd3;
+    platforms = with platforms; linux ++ darwin;
+    maintainers = with maintainers; [ markuskowa ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/aldo/default.nix b/nixpkgs/pkgs/applications/radio/aldo/default.nix
new file mode 100644
index 000000000000..df52531a518d
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/aldo/default.nix
@@ -0,0 +1,21 @@
+{ stdenv, fetchurl, libao }:
+
+stdenv.mkDerivation rec {
+  pname = "aldo";
+  version = "0.7.7";
+
+  src = fetchurl {
+    url = "mirror://savannah/${pname}/${pname}-${version}.tar.bz2";
+    sha256 = "14lzgldqzbbzydsy1cai3wln3hpyj1yhj8ji3wygyzr616fq9f7i";
+  };
+
+  buildInputs = [ libao ];
+
+  meta = with stdenv.lib; {
+    description = "Morse code training program";
+    homepage = "http://aldo.nongnu.org/";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ etu ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/chirp/default.nix b/nixpkgs/pkgs/applications/radio/chirp/default.nix
new file mode 100644
index 000000000000..377619f5088c
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/chirp/default.nix
@@ -0,0 +1,24 @@
+{ stdenv
+, fetchurl
+, python2
+}:
+python2.pkgs.buildPythonApplication rec {
+  pname = "chirp-daily";
+  version = "20200430";
+
+  src = fetchurl {
+    url = "https://trac.chirp.danplanet.com/chirp_daily/daily-${version}/${pname}-${version}.tar.gz";
+    sha256 = "060fzplgmpfrk6wkfaasx7phpfk90mmylk6drbwzk4f9r1655vda";
+  };
+
+  propagatedBuildInputs = with python2.pkgs; [
+    pygtk pyserial libxml2 future
+  ];
+
+  meta = with stdenv.lib; {
+    description = "A free, open-source tool for programming your amateur radio";
+    homepage = "https://chirp.danplanet.com/";
+    license = licenses.gpl3;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/cubicsdr/default.nix b/nixpkgs/pkgs/applications/radio/cubicsdr/default.nix
new file mode 100644
index 000000000000..c85299606c03
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/cubicsdr/default.nix
@@ -0,0 +1,30 @@
+{ stdenv, fetchFromGitHub, cmake, fftw, hamlib, libpulseaudio, libGL, libX11, liquid-dsp,
+  pkgconfig, soapysdr-with-plugins, wxGTK31-gtk3, enableDigitalLab ? false }:
+
+stdenv.mkDerivation rec {
+  pname = "cubicsdr";
+  version = "0.2.5";
+
+  src = fetchFromGitHub {
+    owner = "cjcliffe";
+    repo = "CubicSDR";
+    rev = version;
+    sha256 = "1ihbn18bzdcdvwpa4hnb55ns38bj4b8xy53hkmra809f9qpbcjhn";
+  };
+
+  nativeBuildInputs = [ cmake pkgconfig ];
+
+  buildInputs = [ fftw hamlib libpulseaudio libGL libX11 liquid-dsp soapysdr-with-plugins wxGTK31-gtk3 ];
+
+  cmakeFlags = [ "-DUSE_HAMLIB=ON" ]
+    ++ stdenv.lib.optional enableDigitalLab "-DENABLE_DIGITAL_LAB=ON";
+
+  meta = with stdenv.lib; {
+    homepage = "https://cubicsdr.com";
+    description = "Software Defined Radio application";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ lasandell ];
+    platforms = platforms.linux;
+  };
+}
+
diff --git a/nixpkgs/pkgs/applications/radio/dablin/default.nix b/nixpkgs/pkgs/applications/radio/dablin/default.nix
new file mode 100644
index 000000000000..287649ddbe1e
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/dablin/default.nix
@@ -0,0 +1,28 @@
+{ stdenv, fetchFromGitHub, cmake, pkgconfig
+, mpg123, SDL2, gnome3, faad2, pcre
+} :
+
+stdenv.mkDerivation rec {
+  pname = "dablin";
+  version = "1.13.0";
+
+  src = fetchFromGitHub {
+    owner = "Opendigitalradio";
+    repo = "dablin";
+    rev = version;
+    sha256 = "0143jnhwwh4din6mlrkbm8m2wm8vnrlk0yk9r5qcvj70r2314bgq";
+  };
+
+  nativeBuildInputs = [ cmake pkgconfig ];
+
+  buildInputs = [ faad2 mpg123 SDL2 gnome3.gtkmm pcre ];
+
+  meta = with stdenv.lib; {
+    description = "Play DAB/DAB+ from ETI-NI aligned stream";
+    homepage = "https://github.com/Opendigitalradio/dablin";
+    license = with licenses; [ gpl3 lgpl21 ];
+    platforms = platforms.linux;
+    maintainers = [ maintainers.markuskowa ];
+  };
+}
+
diff --git a/nixpkgs/pkgs/applications/radio/dabtools/default.nix b/nixpkgs/pkgs/applications/radio/dabtools/default.nix
new file mode 100644
index 000000000000..401e207ba4f6
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/dabtools/default.nix
@@ -0,0 +1,27 @@
+{ stdenv, fetchFromGitHub, cmake, pkgconfig
+, libusb1, rtl-sdr, fftw
+} :
+
+stdenv.mkDerivation {
+  pname = "dabtools";
+  version = "20180405";
+
+  src = fetchFromGitHub {
+    owner = "Opendigitalradio";
+    repo = "dabtools";
+    rev = "8b0b2258b02020d314efd4d0d33a56c8097de0d1";
+    sha256 = "18nkdybgg2w6zh56g6xwmg49sifalvraz4rynw8w5d8cqi3dm9sm";
+  };
+
+  nativeBuildInputs = [ cmake pkgconfig ];
+  buildInputs = [ rtl-sdr fftw libusb1 ];
+
+  meta = with stdenv.lib; {
+    description = "Commandline tools for DAB and DAB+ digital radio broadcasts";
+    homepage = "https://github.com/Opendigitalradio/dabtools";
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux;
+    maintainers = [ maintainers.markuskowa ];
+  };
+}
+
diff --git a/nixpkgs/pkgs/applications/radio/dmrconfig/default.nix b/nixpkgs/pkgs/applications/radio/dmrconfig/default.nix
new file mode 100644
index 000000000000..47b72669f8fd
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/dmrconfig/default.nix
@@ -0,0 +1,42 @@
+{ stdenv, fetchFromGitHub
+, libusb1, systemd }:
+
+stdenv.mkDerivation rec {
+  pname = "dmrconfig";
+  version = "1.1";
+
+  src = fetchFromGitHub {
+    owner = "sergev";
+    repo = "dmrconfig";
+    rev = version;
+    sha256 = "1qwix75z749628w583fwp7m7kxbj0k3g159sxb7vgqxbadqqz1ab";
+  };
+
+  buildInputs = [
+    libusb1 systemd
+  ];
+
+  preConfigure = ''
+    substituteInPlace Makefile \
+      --replace /usr/local/bin/dmrconfig $out/bin/dmrconfig
+  '';
+
+  makeFlags = [ "VERSION=${version}" "GITCOUNT=0" ];
+
+  installPhase = ''
+    mkdir -p $out/bin $out/lib/udev/rules.d
+    make install
+    install 99-dmr.rules $out/lib/udev/rules.d/99-dmr.rules
+  '';
+
+  meta = with stdenv.lib; {
+    description = "Configuration utility for DMR radios";
+    longDescription = ''
+      DMRconfig is a utility for programming digital radios via USB programming cable.
+    '';
+    homepage = "https://github.com/sergev/dmrconfig";
+    license = licenses.asl20;
+    maintainers = [ maintainers.etu ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/dump1090/default.nix b/nixpkgs/pkgs/applications/radio/dump1090/default.nix
new file mode 100644
index 000000000000..11c5c46ae681
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/dump1090/default.nix
@@ -0,0 +1,43 @@
+{ stdenv
+, fetchFromGitHub
+, pkgconfig
+, libbladeRF
+, libusb1
+, ncurses
+, rtl-sdr
+}:
+
+stdenv.mkDerivation rec {
+  pname = "dump1090";
+  version = "3.8.1";
+
+  src = fetchFromGitHub {
+    owner = "flightaware";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "0xg8rzrxqklx1m9ncxsd96dlkbjcsxfi2mrb859v50f07xysdyd8";
+  };
+
+  nativeBuildInputs = [ pkgconfig ];
+
+  buildInputs = [
+    libbladeRF
+    libusb1
+    ncurses
+    rtl-sdr
+  ];
+
+  installPhase = ''
+    mkdir -p $out/bin $out/share
+    cp -v dump1090 view1090 $out/bin
+    cp -vr public_html $out/share/dump1090
+  '';
+
+  meta = with stdenv.lib; {
+    description = "A simple Mode S decoder for RTLSDR devices";
+    homepage = "https://github.com/flightaware/dump1090";
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+    maintainers = with maintainers; [ earldouglas ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/ebook2cw/configfile.patch b/nixpkgs/pkgs/applications/radio/ebook2cw/configfile.patch
new file mode 100644
index 000000000000..c7aafe5227a5
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/ebook2cw/configfile.patch
@@ -0,0 +1,11 @@
+--- a/ebook2cw.c	2017-11-08 19:52:58.298131348 -0700
++++ b/ebook2cw.c	2017-11-08 19:53:02.588231067 -0700
+@@ -136,7 +136,7 @@
+ 	char isomap[256][4]; 		/* by these strings */
+ 	char utf8map[256][8];
+ 
+-	char configfile[1025];
++	char configfile[2048];
+ 
+ 	char id3_author[80],
+ 		id3_title[80],
diff --git a/nixpkgs/pkgs/applications/radio/ebook2cw/default.nix b/nixpkgs/pkgs/applications/radio/ebook2cw/default.nix
new file mode 100644
index 000000000000..d273594f4c90
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/ebook2cw/default.nix
@@ -0,0 +1,25 @@
+{ stdenv, fetchsvn, lame, libvorbis }:
+
+stdenv.mkDerivation rec {
+  pname = "ebook2cw";
+  version = "0.8.2";
+
+  src = fetchsvn {
+    url = "svn://svn.fkurz.net/ebook2cw/tags/${pname}-${version}";
+    sha256 = "1mvp3nz3k76v757792n9b7fcm5jm3jcwarl1k7cila9fi0c2rsiw";
+  };
+
+  buildInputs = [ lame libvorbis ];
+
+  patches = [ ./configfile.patch ];
+
+  makeFlags = [ "DESTDIR=$(out)" ];
+
+  meta = with stdenv.lib; {
+    description = "Convert ebooks to Morse MP3s/OGGs";
+    homepage = "http://fkurz.net/ham/ebook2cw.html";
+    license = licenses.gpl2;
+    platforms = platforms.all;
+    maintainers = with maintainers; [ earldouglas ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/fldigi/default.nix b/nixpkgs/pkgs/applications/radio/fldigi/default.nix
new file mode 100644
index 000000000000..b4815803ccde
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/fldigi/default.nix
@@ -0,0 +1,23 @@
+{ stdenv, fetchurl, hamlib, fltk14, libjpeg, libpng, portaudio, libsndfile,
+  libsamplerate, libpulseaudio, libXinerama, gettext, pkgconfig, alsaLib }:
+
+stdenv.mkDerivation rec {
+  version = "4.1.13";
+  pname = "fldigi";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/${pname}/${pname}-${version}.tar.gz";
+    sha256 = "0mlq4z5k3h466plij8hg9xn5xbjxk557g4pw13cplpf32fhng224";
+  };
+
+  buildInputs = [ libXinerama gettext hamlib fltk14 libjpeg libpng portaudio
+                  libsndfile libsamplerate libpulseaudio pkgconfig alsaLib ];
+
+  meta = {
+    description = "Digital modem program";
+    homepage = "https://sourceforge.net/projects/fldigi/";
+    license = stdenv.lib.licenses.gpl3Plus;
+    maintainers = with stdenv.lib.maintainers; [ relrod ftrvxmtrx ];
+    platforms = stdenv.lib.platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/fllog/default.nix b/nixpkgs/pkgs/applications/radio/fllog/default.nix
new file mode 100644
index 000000000000..649caae09021
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/fllog/default.nix
@@ -0,0 +1,33 @@
+{ stdenv
+, fetchurl
+, fltk13
+, libjpeg
+, pkgconfig
+}:
+
+stdenv.mkDerivation rec {
+  version = "1.2.6";
+  pname = "fllog";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/fldigi/${pname}-${version}.tar.gz";
+    sha256 = "18nwqbbg5khpkwlr7dn41g6zf7ms2wzxykd42fwdsj4m4z0ysyyg";
+  };
+
+  buildInputs = [
+    fltk13
+    libjpeg
+  ];
+
+  nativeBuildInputs = [
+    pkgconfig
+  ];
+
+  meta = {
+    description = "Digital modem log program";
+    homepage = "https://sourceforge.net/projects/fldigi/";
+    license = stdenv.lib.licenses.gpl3Plus;
+    maintainers = with stdenv.lib.maintainers; [ dysinger ];
+    platforms = stdenv.lib.platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/flmsg/default.nix b/nixpkgs/pkgs/applications/radio/flmsg/default.nix
new file mode 100644
index 000000000000..e437dffa4856
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/flmsg/default.nix
@@ -0,0 +1,33 @@
+{ stdenv
+, fetchurl
+, fltk13
+, libjpeg
+, pkgconfig
+}:
+
+stdenv.mkDerivation rec {
+  version = "4.0.14";
+  pname = "flmsg";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/fldigi/${pname}-${version}.tar.gz";
+    sha256 = "0s1prawkpvr7xr7h8w7r0ly90ya3n8h6qsii0x6laqrkgjn9w9iy";
+  };
+
+  buildInputs = [
+    fltk13
+    libjpeg
+  ];
+
+  nativeBuildInputs = [
+    pkgconfig
+  ];
+
+  meta = {
+    description = "Digital modem message program";
+    homepage = "https://sourceforge.net/projects/fldigi/";
+    license = stdenv.lib.licenses.gpl3Plus;
+    maintainers = with stdenv.lib.maintainers; [ dysinger ];
+    platforms = stdenv.lib.platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/flrig/default.nix b/nixpkgs/pkgs/applications/radio/flrig/default.nix
new file mode 100644
index 000000000000..968b2fd0df9b
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/flrig/default.nix
@@ -0,0 +1,33 @@
+{ stdenv
+, fetchurl
+, fltk13
+, libjpeg
+, pkgconfig
+}:
+
+stdenv.mkDerivation rec {
+  version = "1.3.50";
+  pname = "flrig";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/fldigi/${pname}-${version}.tar.gz";
+    sha256 = "0fzrknzzi8kmzmrcfpc8rxr7v4a4ny6z6z5q5qwh95sp2kn2qzp9";
+  };
+
+  buildInputs = [
+    fltk13
+    libjpeg
+  ];
+
+  nativeBuildInputs = [
+    pkgconfig
+  ];
+
+  meta = {
+    description = "Digital modem rig control program";
+    homepage = "https://sourceforge.net/projects/fldigi/";
+    license = stdenv.lib.licenses.gpl3Plus;
+    maintainers = with stdenv.lib.maintainers; [ dysinger ];
+    platforms = stdenv.lib.platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/flwrap/default.nix b/nixpkgs/pkgs/applications/radio/flwrap/default.nix
new file mode 100644
index 000000000000..889c212de4e9
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/flwrap/default.nix
@@ -0,0 +1,33 @@
+{ stdenv
+, fetchurl
+, fltk13
+, libjpeg
+, pkgconfig
+}:
+
+stdenv.mkDerivation rec {
+  version = "1.3.5";
+  pname = "flwrap";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/fldigi/${pname}-${version}.tar.gz";
+    sha256 = "0qqivqkkravcg7j45740xfky2q3k7czqpkj6y364qff424q2pppg";
+  };
+
+  buildInputs = [
+    fltk13
+    libjpeg
+  ];
+
+  nativeBuildInputs = [
+    pkgconfig
+  ];
+
+  meta = {
+    description = "Digital modem file transfer program";
+    homepage = "https://sourceforge.net/projects/fldigi/";
+    license = stdenv.lib.licenses.gpl3Plus;
+    maintainers = with stdenv.lib.maintainers; [ dysinger ];
+    platforms = stdenv.lib.platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/gnss-sdr/default.nix b/nixpkgs/pkgs/applications/radio/gnss-sdr/default.nix
new file mode 100644
index 000000000000..4e423094e90e
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/gnss-sdr/default.nix
@@ -0,0 +1,80 @@
+{ stdenv, fetchFromGitHub
+, armadillo
+, boost
+, cmake
+, glog
+, gmock
+, openssl
+, gflags
+, gnuradio
+, orc
+, pkgconfig
+, pythonPackages
+, uhd
+, log4cpp
+, blas, lapack
+, matio
+, pugixml
+, protobuf
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnss-sdr";
+  version = "0.0.12";
+
+  src = fetchFromGitHub {
+    owner = "gnss-sdr";
+    repo = "gnss-sdr";
+    rev = "v${version}";
+    sha256 = "0i9cz85jc2m758pzy3bq4dk4vj9wv7k2z118lasb09xldx01dwsq";
+  };
+
+  buildInputs = [
+    armadillo
+    boost.dev
+    cmake
+    glog
+    gmock
+    openssl.dev
+    gflags
+    gnuradio
+    orc
+    pkgconfig
+    pythonPackages.Mako
+
+    # UHD support is optional, but gnuradio is built with it, so there's
+    # nothing to be gained by leaving it out.
+    uhd
+    log4cpp
+    blas lapack
+    matio
+    pugixml
+    protobuf
+  ];
+
+  enableParallelBuilding = true;
+
+  cmakeFlags = [
+    "-DGFlags_ROOT_DIR=${gflags}/lib"
+    "-DGLOG_INCLUDE_DIR=${glog}/include"
+    "-DENABLE_UNIT_TESTING=OFF"
+
+    # gnss-sdr doesn't truly depend on BLAS or LAPACK, as long as
+    # armadillo is built using both, so skip checking for them.
+    "-DBLAS=YES"
+    "-DLAPACK=YES"
+    "-DBLAS_LIBRARIES=-lblas"
+    "-DLAPACK_LIBRARIES=-llapack"
+
+    # Similarly, it doesn't actually use gfortran despite checking for
+    # its presence.
+    "-DGFORTRAN=YES"
+  ];
+
+  meta = with stdenv.lib; {
+    description = "An open source Global Navigation Satellite Systems software-defined receiver";
+    homepage = "https://gnss-sdr.org/";
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/gnuradio/ais.nix b/nixpkgs/pkgs/applications/radio/gnuradio/ais.nix
new file mode 100644
index 000000000000..30c2638a72f8
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/gnuradio/ais.nix
@@ -0,0 +1,40 @@
+{ stdenv, fetchFromGitHub, cmake, pkgconfig, boost, gnuradio
+, makeWrapper, cppunit, gr-osmosdr
+, pythonSupport ? true, python, swig
+}:
+
+assert pythonSupport -> python != null && swig != null;
+
+stdenv.mkDerivation {
+  pname = "gr-ais";
+  version = "2015-12-20";
+
+  src = fetchFromGitHub {
+    owner = "bistromath";
+    repo = "gr-ais";
+    # Upstream PR: https://github.com/bistromath/gr-ais/commit/8502d0252a2a1a9b8d1a71795eaeb5d820684054
+    rev = "8502d0252a2a1a9b8d1a71795eaeb5d820684054";
+    sha256 = "1b9j0kc74cw12a7jv4lii77dgzqzg2s8ndzp4xmisxksgva1qfvh";
+  };
+
+  nativeBuildInputs = [ pkgconfig ];
+  buildInputs = [
+    cmake boost gnuradio makeWrapper cppunit gr-osmosdr
+  ] ++ stdenv.lib.optionals pythonSupport [ python swig ];
+
+  postInstall = ''
+    for prog in "$out"/bin/*; do
+        wrapProgram "$prog" --set PYTHONPATH $PYTHONPATH:$(toPythonPath "$out")
+    done
+  '';
+
+  enableParallelBuilding = true;
+
+  meta = with stdenv.lib; {
+    description = "Gnuradio block for ais";
+    homepage = "https://github.com/bistromath/gr-ais";
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux ++ platforms.darwin;
+    maintainers = with maintainers; [ mog ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/gnuradio/default.nix b/nixpkgs/pkgs/applications/radio/gnuradio/default.nix
new file mode 100644
index 000000000000..dec968cd32d7
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/gnuradio/default.nix
@@ -0,0 +1,165 @@
+{ stdenv
+, fetchFromGitHub
+, makeWrapper
+, writeText
+# Dependencies documented @ https://gnuradio.org/doc/doxygen/build_guide.html
+# => core dependencies
+, cmake
+, pkgconfig
+, git
+, boost
+, cppunit
+, fftw
+# => python wrappers
+# May be able to upgrade to swig3
+, python
+, swig2
+, numpy
+, scipy
+, matplotlib
+# => grc - the gnu radio companion
+, Mako
+, cheetah
+, pygtk # Note: GR is migrating to Mako. Cheetah should be removed for GR3.8
+# => gr-wavelet: collection of wavelet blocks
+, gsl
+# => gr-qtgui: the Qt-based GUI
+, qt4
+, qwt
+, pyqt4
+# => gr-wxgui: the Wx-based GUI
+, wxPython
+, lxml
+# => gr-audio: audio subsystems (system/OS dependent)
+, alsaLib   # linux   'audio-alsa'
+, CoreAudio # darwin  'audio-osx'
+# => uhd: the Ettus USRP Hardware Driver Interface
+, uhd
+# => gr-video-sdl: PAL and NTSC display
+, SDL
+# Other
+, libusb1
+, orc
+, pyopengl
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnuradio";
+  version = "3.7.14.0";
+
+  src = fetchFromGitHub {
+    owner = "gnuradio";
+    repo = "gnuradio";
+    rev = "v${version}";
+    sha256 = "1nh4f9dmygprlbqybd3j1byg9fsr6065n140mvc4b0v8qqygmhrc";
+    fetchSubmodules = true;
+  };
+
+  nativeBuildInputs = [
+    cmake
+    pkgconfig
+    git
+    makeWrapper
+    cppunit
+    orc
+  ];
+
+  buildInputs = [
+    boost
+    fftw
+    python
+    swig2
+    lxml
+    qt4
+    qwt
+    SDL
+    libusb1
+    uhd
+    gsl
+  ] ++ stdenv.lib.optionals stdenv.isLinux  [ alsaLib   ]
+    ++ stdenv.lib.optionals stdenv.isDarwin [ CoreAudio ];
+
+  propagatedBuildInputs = [
+    Mako
+    cheetah
+    numpy
+    scipy
+    matplotlib
+    pyqt4
+    pygtk
+    wxPython
+    pyopengl
+  ];
+
+  NIX_LDFLAGS = "-lpthread";
+
+  enableParallelBuilding = true;
+
+  postPatch = ''
+    substituteInPlace \
+        gr-fec/include/gnuradio/fec/polar_decoder_common.h \
+        --replace BOOST_CONSTEXPR_OR_CONST const
+  '';
+
+  # Enables composition with nix-shell
+  grcSetupHook = writeText "grcSetupHook.sh" ''
+    addGRCBlocksPath() {
+      addToSearchPath GRC_BLOCKS_PATH $1/share/gnuradio/grc/blocks
+    }
+    addEnvHooks "$targetOffset" addGRCBlocksPath
+  '';
+
+  setupHook = [ grcSetupHook ];
+
+  # patch wxgui and pygtk check due to python importerror in a headless environment
+  # wxgtk gui will be removed in GR3.8
+  # c++11 hack may not be necessary anymore
+  preConfigure = ''
+    export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -Wno-unused-variable ${stdenv.lib.optionalString (!stdenv.isDarwin) "-std=c++11"}"
+    sed -i 's/.*wx\.version.*/set(WX_FOUND TRUE)/g' gr-wxgui/CMakeLists.txt
+    sed -i 's/.*pygtk_version.*/set(PYGTK_FOUND TRUE)/g' grc/CMakeLists.txt
+    find . -name "CMakeLists.txt" -exec sed -i '1iadd_compile_options($<$<COMPILE_LANGUAGE:CXX>:-std=c++11>)' "{}" ";"
+  '';
+
+  # Framework path needed for qwt6_qt4 but not qwt5
+  cmakeFlags =
+    stdenv.lib.optionals stdenv.isDarwin [ "-DCMAKE_FRAMEWORK_PATH=${qwt}/lib" ];
+
+  # - Ensure we get an interactive backend for matplotlib. If not the gr_plot_*
+  #   programs will not display anything. Yes, $MATPLOTLIBRC must point to the
+  #   *dirname* where matplotlibrc is located, not the file itself.
+  # - GNU Radio core is C++ but the user interface (GUI and API) is Python, so
+  #   we must wrap the stuff in bin/.
+  # Notes:
+  # - May want to use makeWrapper instead of wrapProgram
+  # - may want to change interpreter path on Python examples instead of wrapping
+  # - see https://github.com/NixOS/nixpkgs/issues/22688 regarding use of --prefix / python.withPackages
+  # - see https://github.com/NixOS/nixpkgs/issues/24693 regarding use of DYLD_FRAMEWORK_PATH on Darwin
+  postInstall = ''
+    printf "backend : Qt4Agg\n" > "$out/share/gnuradio/matplotlibrc"
+
+    for file in $(find $out/bin $out/share/gnuradio/examples -type f -executable); do
+        wrapProgram "$file" \
+            --prefix PYTHONPATH : $PYTHONPATH:$(toPythonPath "$out") \
+            --set MATPLOTLIBRC "$out/share/gnuradio" \
+            ${stdenv.lib.optionalString stdenv.isDarwin "--set DYLD_FRAMEWORK_PATH /System/Library/Frameworks"}
+    done
+  '';
+
+  meta = with stdenv.lib; {
+    description = "Software Defined Radio (SDR) software";
+    longDescription = ''
+      GNU Radio is a free & open-source software development toolkit that
+      provides signal processing blocks to implement software radios. It can be
+      used with readily-available low-cost external RF hardware to create
+      software-defined radios, or without hardware in a simulation-like
+      environment. It is widely used in hobbyist, academic and commercial
+      environments to support both wireless communications research and
+      real-world radio systems.
+    '';
+    homepage = "https://www.gnuradio.org";
+    license = licenses.gpl3;
+    platforms = platforms.linux ++ platforms.darwin;
+    maintainers = with maintainers; [ bjornfor fpletz ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/gnuradio/gsm.nix b/nixpkgs/pkgs/applications/radio/gnuradio/gsm.nix
new file mode 100644
index 000000000000..e0b8d7dd44f7
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/gnuradio/gsm.nix
@@ -0,0 +1,39 @@
+{ stdenv, fetchFromGitHub, cmake, pkgconfig, boost, gnuradio
+, makeWrapper, cppunit, libosmocore, gr-osmosdr
+, pythonSupport ? true, python, swig
+}:
+
+assert pythonSupport -> python != null && swig != null;
+
+stdenv.mkDerivation {
+  pname = "gr-gsm";
+  version = "2016-08-25";
+
+  src = fetchFromGitHub {
+    owner = "ptrkrysik";
+    repo = "gr-gsm";
+    rev = "3ca05e6914ef29eb536da5dbec323701fbc2050d";
+    sha256 = "13nnq927kpf91iqccr8db9ripy5czjl5jiyivizn6bia0bam2pvx";
+  };
+
+  nativeBuildInputs = [ pkgconfig ];
+  buildInputs = [
+    cmake boost gnuradio makeWrapper cppunit libosmocore gr-osmosdr
+  ] ++ stdenv.lib.optionals pythonSupport [ python swig ];
+
+  postInstall = ''
+    for prog in "$out"/bin/*; do
+        wrapProgram "$prog" --set PYTHONPATH $PYTHONPATH:${gr-osmosdr}/lib/${python.libPrefix}/site-packages:$(toPythonPath "$out")
+    done
+  '';
+
+  enableParallelBuilding = true;
+
+  meta = with stdenv.lib; {
+    description = "Gnuradio block for gsm";
+    homepage = "https://github.com/ptrkrysik/gr-gsm";
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux;
+    maintainers = with maintainers; [ mog ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/gnuradio/limesdr.nix b/nixpkgs/pkgs/applications/radio/gnuradio/limesdr.nix
new file mode 100644
index 000000000000..490caaaa7bea
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/gnuradio/limesdr.nix
@@ -0,0 +1,40 @@
+{ stdenv, fetchFromGitHub, cmake, pkgconfig, boost, gnuradio
+, pythonSupport ? true, python, swig, limesuite
+} :
+
+assert pythonSupport -> python != null && swig != null;
+
+let
+  version = "2.0.0";
+
+in stdenv.mkDerivation {
+  pname = "gr-limesdr";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "myriadrf";
+    repo = "gr-limesdr";
+    rev = "v${version}";
+    sha256 = "0ldqvfwl0gil89l9s31fjf9d7ki0dk572i8vna336igfaz348ypq";
+  };
+
+  nativeBuildInputs = [
+    cmake
+    pkgconfig
+  ] ++ stdenv.lib.optionals pythonSupport [ swig ];
+
+  buildInputs = [
+    boost gnuradio limesuite
+  ] ++ stdenv.lib.optionals pythonSupport [ python ];
+
+
+  enableParallelBuilding = true;
+
+  meta = with stdenv.lib; {
+    description = "Gnuradio source and sink blocks for LimeSDR";
+    homepage = "https://wiki.myriadrf.org/Gr-limesdr_Plugin_for_GNURadio";
+    license = licenses.mit;
+    platforms = platforms.linux;
+    maintainers = [ maintainers.markuskowa ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/gnuradio/nacl.nix b/nixpkgs/pkgs/applications/radio/gnuradio/nacl.nix
new file mode 100644
index 000000000000..e3d851e2e14a
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/gnuradio/nacl.nix
@@ -0,0 +1,39 @@
+{ stdenv, fetchFromGitHub, cmake, pkgconfig, boost, gnuradio, uhd
+, makeWrapper, libsodium, cppunit
+, pythonSupport ? true, python, swig
+}:
+
+assert pythonSupport -> python != null && swig != null;
+
+stdenv.mkDerivation {
+  pname = "gr-nacl";
+  version = "2017-04-10";
+
+  src = fetchFromGitHub {
+    owner = "stwunsch";
+    repo = "gr-nacl";
+    rev = "15276bb0fcabf5fe4de4e58df3d579b5be0e9765";
+    sha256 = "018np0qlk61l7mlv3xxx5cj1rax8f1vqrsrch3higsl25yydbv7v";
+  };
+
+  nativeBuildInputs = [ pkgconfig ];
+  buildInputs = [
+    cmake boost gnuradio uhd makeWrapper libsodium cppunit
+  ] ++ stdenv.lib.optionals pythonSupport [ python swig ];
+
+  postInstall = ''
+    for prog in "$out"/bin/*; do
+        wrapProgram "$prog" --set PYTHONPATH $PYTHONPATH:$(toPythonPath "$out")
+    done
+  '';
+
+  enableParallelBuilding = true;
+
+  meta = with stdenv.lib; {
+    description = "Gnuradio block for encryption";
+    homepage = "https://github.com/stwunsch/gr-nacl";
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux ++ platforms.darwin;
+    maintainers = with maintainers; [ mog ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/gnuradio/osmosdr.nix b/nixpkgs/pkgs/applications/radio/gnuradio/osmosdr.nix
new file mode 100644
index 000000000000..ad54fc8d7c4f
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/gnuradio/osmosdr.nix
@@ -0,0 +1,47 @@
+{ stdenv, fetchgit, cmake, pkgconfig, makeWrapper
+, boost
+, pythonSupport ? true, python, swig
+, airspy
+, gnuradio
+, hackrf
+, libbladeRF
+, rtl-sdr
+, soapysdr-with-plugins
+, uhd
+}:
+
+assert pythonSupport -> python != null && swig != null;
+
+stdenv.mkDerivation rec {
+  pname = "gr-osmosdr";
+  version = "0.1.5";
+
+  src = fetchgit {
+    url = "git://git.osmocom.org/gr-osmosdr";
+    rev = "v${version}";
+    sha256 = "0bf9bnc1c3c4yqqqgmg3nhygj6rcfmyk6pybi27f7461d2cw1drv";
+  };
+
+  nativeBuildInputs = [ pkgconfig ];
+  buildInputs = [
+    cmake makeWrapper boost
+    airspy gnuradio hackrf libbladeRF rtl-sdr uhd
+  ] ++ stdenv.lib.optionals stdenv.isLinux [ soapysdr-with-plugins ]
+    ++ stdenv.lib.optionals pythonSupport [ python swig ];
+
+  postInstall = ''
+    for prog in "$out"/bin/*; do
+        wrapProgram "$prog" --set PYTHONPATH $PYTHONPATH:$(toPythonPath "$out")
+    done
+  '';
+
+  enableParallelBuilding = true;
+
+  meta = with stdenv.lib; {
+    description = "Gnuradio block for OsmoSDR and rtl-sdr";
+    homepage = "https://sdr.osmocom.org/trac/wiki/GrOsmoSDR";
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux ++ platforms.darwin;
+    maintainers = with maintainers; [ bjornfor ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/gnuradio/rds.nix b/nixpkgs/pkgs/applications/radio/gnuradio/rds.nix
new file mode 100644
index 000000000000..1f8ed211ef29
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/gnuradio/rds.nix
@@ -0,0 +1,38 @@
+{ stdenv, fetchFromGitHub, cmake, pkgconfig, boost, gnuradio
+, makeWrapper, pythonSupport ? true, python, swig
+}:
+
+assert pythonSupport -> python != null && swig != null;
+
+stdenv.mkDerivation rec {
+  pname = "gr-rds";
+  version = "1.1.0";
+
+  src = fetchFromGitHub {
+    owner = "bastibl";
+    repo = "gr-rds";
+    rev = "v${version}";
+    sha256 = "0jkzchvw0ivcxsjhi1h0mf7k13araxf5m4wi5v9xdgqxvipjzqfy";
+  };
+
+  nativeBuildInputs = [ pkgconfig ];
+  buildInputs = [
+    cmake boost gnuradio makeWrapper
+  ] ++ stdenv.lib.optionals pythonSupport [ python swig ];
+
+  postInstall = ''
+    for prog in "$out"/bin/*; do
+        wrapProgram "$prog" --set PYTHONPATH $PYTHONPATH:$(toPythonPath "$out")
+    done
+  '';
+
+  enableParallelBuilding = true;
+
+  meta = with stdenv.lib; {
+    description = "Gnuradio block for radio data system";
+    homepage = "https://github.com/bastibl/gr-rds";
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux ++ platforms.darwin;
+    maintainers = with maintainers; [ mog ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/gnuradio/wrapper.nix b/nixpkgs/pkgs/applications/radio/gnuradio/wrapper.nix
new file mode 100644
index 000000000000..ffed3da03187
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/gnuradio/wrapper.nix
@@ -0,0 +1,24 @@
+{ stdenv, gnuradio, makeWrapper, python, extraPackages ? [] }:
+
+with { inherit (stdenv.lib) appendToName makeSearchPath; };
+
+stdenv.mkDerivation {
+  name = (appendToName "with-packages" gnuradio).name;
+  buildInputs = [ makeWrapper python ];
+
+  buildCommand = ''
+    mkdir -p $out/bin
+    ln -s "${gnuradio}"/bin/* $out/bin/
+
+    for file in $(find -L $out/bin -type f); do
+        if test -x "$(readlink -f "$file")"; then
+            wrapProgram "$file" \
+                --prefix PYTHONPATH : ${stdenv.lib.concatStringsSep ":"
+                                         (map (path: "$(toPythonPath ${path})") extraPackages)} \
+                --prefix GRC_BLOCKS_PATH : ${makeSearchPath "share/gnuradio/grc/blocks" extraPackages}
+        fi
+    done
+  '';
+
+  inherit (gnuradio) meta;
+}
diff --git a/nixpkgs/pkgs/applications/radio/gqrx/default.nix b/nixpkgs/pkgs/applications/radio/gqrx/default.nix
new file mode 100644
index 000000000000..33b858799e2a
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/gqrx/default.nix
@@ -0,0 +1,48 @@
+{ stdenv, fetchFromGitHub, cmake, qtbase, qtsvg, gnuradio, boost, gr-osmosdr
+, mkDerivation
+# drivers (optional):
+, rtl-sdr, hackrf
+, pulseaudioSupport ? true, libpulseaudio
+}:
+
+assert pulseaudioSupport -> libpulseaudio != null;
+
+mkDerivation rec {
+  pname = "gqrx";
+  version = "2.12.1";
+
+  src = fetchFromGitHub {
+    owner = "csete";
+    repo = "gqrx";
+    rev = "v${version}";
+    sha256 = "00alf3q6y313xpx6p7v43vqsphd2x4am4q362lw21bcy9wc4jidw";
+  };
+
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [
+    qtbase qtsvg gnuradio boost gr-osmosdr rtl-sdr hackrf
+  ] ++ stdenv.lib.optionals pulseaudioSupport [ libpulseaudio ];
+
+  enableParallelBuilding = true;
+
+  postInstall = ''
+    install -vD $src/gqrx.desktop -t "$out/share/applications/"
+    install -vD $src/resources/icons/gqrx.svg -t "$out/share/icons/"
+  '';
+
+  meta = with stdenv.lib; {
+    description = "Software defined radio (SDR) receiver";
+    longDescription = ''
+      Gqrx is a software defined radio receiver powered by GNU Radio and the Qt
+      GUI toolkit. It can process I/Q data from many types of input devices,
+      including Funcube Dongle Pro/Pro+, rtl-sdr, HackRF, and Universal
+      Software Radio Peripheral (USRP) devices.
+    '';
+    homepage = "https://gqrx.dk/";
+    # Some of the code comes from the Cutesdr project, with a BSD license, but
+    # it's currently unknown which version of the BSD license that is.
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux;  # should work on Darwin / macOS too
+    maintainers = with maintainers; [ bjornfor fpletz ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/hackrf/default.nix b/nixpkgs/pkgs/applications/radio/hackrf/default.nix
new file mode 100644
index 000000000000..dfd7fabcc6e0
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/hackrf/default.nix
@@ -0,0 +1,37 @@
+{ stdenv, fetchFromGitHub, cmake, pkgconfig, libusb1, fftwSinglePrec }:
+
+stdenv.mkDerivation rec {
+  pname = "hackrf";
+  version = "2018.01.1";
+
+  src = fetchFromGitHub {
+    owner = "mossmann";
+    repo = "hackrf";
+    rev = "v${version}";
+    sha256 = "0idh983xh6gndk9kdgx5nzz76x3mxb42b02c5xvdqahadsfx3b9w";
+  };
+
+  nativeBuildInputs = [
+    cmake
+    pkgconfig
+  ];
+
+  buildInputs = [
+    libusb1
+    fftwSinglePrec
+  ];
+
+  cmakeFlags = [ "-DUDEV_RULES_GROUP=plugdev" "-DUDEV_RULES_PATH=lib/udev/rules.d" ];
+
+  preConfigure = ''
+    cd host
+  '';
+
+  meta = with stdenv.lib; {
+    description = "An open source SDR platform";
+    homepage = "http://greatscottgadgets.com/hackrf/";
+    license = licenses.gpl2;
+    platforms = platforms.all;
+    maintainers = with maintainers; [ sjmackenzie ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/inspectrum/default.nix b/nixpkgs/pkgs/applications/radio/inspectrum/default.nix
new file mode 100644
index 000000000000..a205cec714d8
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/inspectrum/default.nix
@@ -0,0 +1,40 @@
+{ lib
+, mkDerivation
+, fetchFromGitHub
+, pkgconfig
+, cmake
+, boost
+, fftwFloat
+, gnuradio
+, liquid-dsp
+, qtbase
+}:
+
+mkDerivation {
+  pname = "inspectrum";
+  version = "unstable-2017-05-31";
+
+  src = fetchFromGitHub {
+    owner = "miek";
+    repo = "inspectrum";
+    rev = "a89d1337efb31673ccb6a6681bb89c21894c76f7";
+    sha256 = "1fvnr8gca25i6s9mg9b2hyqs0zzr4jicw13mimc9dhrgxklrr1yv";
+  };
+
+  nativeBuildInputs = [ cmake pkgconfig ];
+  buildInputs = [
+    fftwFloat
+    boost
+    gnuradio
+    liquid-dsp
+    qtbase
+  ];
+
+  meta = with lib; {
+    description = "Tool for analysing captured signals from sdr receivers";
+    homepage = "https://github.com/miek/inspectrum";
+    maintainers = with maintainers; [ mog ];
+    platforms = platforms.linux;
+    license = licenses.gpl3Plus;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/kalibrate-hackrf/default.nix b/nixpkgs/pkgs/applications/radio/kalibrate-hackrf/default.nix
new file mode 100644
index 000000000000..273d2d8c8e37
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/kalibrate-hackrf/default.nix
@@ -0,0 +1,37 @@
+{ stdenv, fetchFromGitHub, autoreconfHook, pkgconfig, fftw, hackrf, libusb1 }:
+
+stdenv.mkDerivation {
+  name = "kalibrate-hackrf-unstable-20160827";
+
+  # There are no tags/releases, so use the latest commit from git master.
+  # Currently, the latest commit is from 2016-07-03.
+  src = fetchFromGitHub {
+    owner = "scateu";
+    repo = "kalibrate-hackrf";
+    rev = "2492c20822ca6a49dce97967caf394b1d4b2c43e";
+    sha256 = "1jvn1qx7csgycxpx1k804sm9gk5a0c65z9gh8ybp9awq3pziv0nx";
+  };
+
+  nativeBuildInputs = [ autoreconfHook pkgconfig ];
+
+  buildInputs = [ fftw hackrf libusb1 ];
+
+  postInstall = ''
+    mv $out/bin/kal $out/bin/kal-hackrf
+  '';
+
+  meta = with stdenv.lib; {
+    description = "Calculate local oscillator frequency offset in hackrf devices";
+    longDescription = ''
+      Kalibrate, or kal, can scan for GSM base stations in a given frequency
+      band and can use those GSM base stations to calculate the local
+      oscillator frequency offset.
+
+      This package is for hackrf devices.
+    '';
+    homepage = "https://github.com/scateu/kalibrate-hackrf";
+    license = licenses.bsd2;
+    platforms = platforms.linux;
+    maintainers = [ maintainers.mog ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/kalibrate-rtl/default.nix b/nixpkgs/pkgs/applications/radio/kalibrate-rtl/default.nix
new file mode 100644
index 000000000000..38913e827d09
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/kalibrate-rtl/default.nix
@@ -0,0 +1,31 @@
+{ stdenv, fetchgit, autoreconfHook, pkgconfig, fftw, rtl-sdr, libusb1 }:
+
+stdenv.mkDerivation {
+  name = "kalibrate-rtl-20131214";
+
+  # There are no tags/releases, so use the latest commit from git master.
+  # Currently, the latest commit is from 2013-12-14.
+  src = fetchgit {
+    url = "https://github.com/steve-m/kalibrate-rtl.git";
+    rev = "aae11c8a8dc79692a94ccfee39ba01e8c8c05d38";
+    sha256 = "1spbfflkqnw9s8317ppsf7b1nnkicqsmaqsnz1zf8i49ix70i6kn";
+  };
+
+  nativeBuildInputs = [ autoreconfHook pkgconfig ];
+  buildInputs = [ fftw rtl-sdr libusb1 ];
+
+  meta = with stdenv.lib; {
+    description = "Calculate local oscillator frequency offset in RTL-SDR devices";
+    longDescription = ''
+      Kalibrate, or kal, can scan for GSM base stations in a given frequency
+      band and can use those GSM base stations to calculate the local
+      oscillator frequency offset.
+
+      This package is for RTL-SDR devices.
+    '';
+    homepage = "https://github.com/steve-m/kalibrate-rtl";
+    license = licenses.bsd2;
+    platforms = platforms.linux;
+    maintainers = [ maintainers.bjornfor ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/limesuite/default.nix b/nixpkgs/pkgs/applications/radio/limesuite/default.nix
new file mode 100644
index 000000000000..7cadceab5611
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/limesuite/default.nix
@@ -0,0 +1,48 @@
+{ stdenv, fetchFromGitHub, cmake
+, sqlite, wxGTK30-gtk3, libusb1, soapysdr
+, mesa_glu, libX11, gnuplot, fltk
+} :
+
+stdenv.mkDerivation rec {
+  pname = "limesuite";
+  version = "20.01.0";
+
+  src = fetchFromGitHub {
+    owner = "myriadrf";
+    repo = "LimeSuite";
+    rev = "v${version}";
+    sha256 = "01z4idcby2lm34bbnpbp400ski7p61jjiir6sy6dalnvsl52m7vx";
+  };
+
+  nativeBuildInputs = [ cmake ];
+
+  cmakeFlags = [
+    "-DOpenGL_GL_PREFERENCE=GLVND"
+  ];
+
+  buildInputs = [
+    libusb1
+    sqlite
+    wxGTK30-gtk3
+    fltk
+    gnuplot
+    libusb1
+    soapysdr
+    mesa_glu
+    libX11
+  ];
+
+  postInstall = ''
+    install -Dm444 -t $out/lib/udev/rules.d ../udev-rules/64-limesuite.rules
+    install -Dm444 -t $out/share/limesuite bin/Release/lms7suite_mcu/*
+  '';
+
+  meta = with stdenv.lib; {
+    description = "Driver and GUI for LMS7002M-based SDR platforms";
+    homepage = "https://github.com/myriadrf/LimeSuite";
+    license = licenses.asl20;
+    maintainers = with maintainers; [ markuskowa ];
+    platforms = platforms.linux;
+  };
+}
+
diff --git a/nixpkgs/pkgs/applications/radio/minimodem/default.nix b/nixpkgs/pkgs/applications/radio/minimodem/default.nix
new file mode 100644
index 000000000000..e94561e46dc8
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/minimodem/default.nix
@@ -0,0 +1,41 @@
+{ stdenv, fetchFromGitHub, pkgconfig, autoconf, automake, libtool
+, fftw, fftwSinglePrec, alsaLib, libsndfile, libpulseaudio
+}:
+
+stdenv.mkDerivation rec {
+  version = "0.24-1";
+  pname = "minimodem";
+
+  src = fetchFromGitHub {
+    owner = "kamalmostafa";
+    repo = "minimodem";
+    rev = "${pname}-${version}";
+    sha256 = "1b5xy36fjcp7vkp115dpx4mlmqg2fc7xvxdy648fb8im953bw7ql";
+  };
+
+  nativeBuildInputs = [ pkgconfig autoconf automake libtool ];
+  buildInputs = [ fftw fftwSinglePrec alsaLib libsndfile libpulseaudio ];
+
+  preConfigure = ''
+    aclocal \
+    && autoheader \
+    && automake --gnu --add-missing \
+    && autoconf
+  '';
+
+  meta = {
+    description = "General-purpose software audio FSK modem";
+    longDescription = ''
+    Minimodem is a command-line program which decodes (or generates) audio
+    modem tones at any specified baud rate, using various framing protocols. It
+    acts a general-purpose software FSK modem, and includes support for various
+    standard FSK protocols such as Bell103, Bell202, RTTY, NOAA SAME, and
+    Caller-ID.
+    '';
+    homepage = "http://www.whence.com/minimodem/";
+    license = stdenv.lib.licenses.gpl3Plus;
+    platforms = with stdenv.lib.platforms; linux;
+    maintainers = with stdenv.lib.maintainers; [ relrod ];
+  };
+}
+
diff --git a/nixpkgs/pkgs/applications/radio/multimon-ng/default.nix b/nixpkgs/pkgs/applications/radio/multimon-ng/default.nix
new file mode 100644
index 000000000000..e275db4ad919
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/multimon-ng/default.nix
@@ -0,0 +1,43 @@
+{ stdenv, fetchFromGitHub, qt4, qmake4Hook, libpulseaudio }:
+let
+  version = "1.1.8";
+in
+stdenv.mkDerivation {
+  pname = "multimon-ng";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "EliasOenal";
+    repo = "multimon-ng";
+    rev = version;
+    sha256 = "1973xfyvzl1viz19zr83cgqlx5laxbjrca35rqabn6dlb6xb5xk8";
+  };
+
+  buildInputs = [ qt4 libpulseaudio ];
+
+  nativeBuildInputs = [ qmake4Hook ];
+
+  qmakeFlags = [ "multimon-ng.pro" ];
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp multimon-ng $out/bin
+  '';
+
+  meta = with stdenv.lib; {
+    description = "Multimon is a digital baseband audio protocol decoder";
+    longDescription = ''
+      multimon-ng a fork of multimon, a digital baseband audio
+      protocol decoder for common signaling modes in commercial and
+      amateur radio data services. It decodes the following digital
+      transmission modes:
+
+      POCSAG512 POCSAG1200 POCSAG2400 EAS UFSK1200 CLIPFSK AFSK1200
+      AFSK2400 AFSK2400_2 AFSK2400_3 HAPN4800 FSK9600 DTMF ZVEI1 ZVEI2
+      ZVEI3 DZVEI PZVEI EEA EIA CCIR MORSE CW
+    '';
+    homepage = "https://github.com/EliasOenal/multimon-ng";
+    license = licenses.gpl2;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/pyradio/default.nix b/nixpkgs/pkgs/applications/radio/pyradio/default.nix
new file mode 100644
index 000000000000..f23359688c6c
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/pyradio/default.nix
@@ -0,0 +1,24 @@
+{ lib, python3Packages, fetchFromGitHub }:
+
+python3Packages.buildPythonApplication rec {
+  pname = "pyradio";
+  version = "0.8.7.2";
+
+  src = fetchFromGitHub {
+    owner = "coderholic";
+    repo = pname;
+    rev = version;
+    sha256 = "0h2sxaqpmc1d1kpvpbcs9wymgzhx25x0x9p7dbyfw9r90i6123q1";
+  };
+
+  checkPhase = ''
+    $out/bin/pyradio --help
+  '';
+
+  meta = with lib; {
+    homepage = "http://www.coderholic.com/pyradio/";
+    description = "Curses based internet radio player";
+    license = licenses.mit;
+    maintainers = with maintainers; [ contrun ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/qradiolink/default.nix b/nixpkgs/pkgs/applications/radio/qradiolink/default.nix
new file mode 100644
index 000000000000..4c792811dc59
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/qradiolink/default.nix
@@ -0,0 +1,60 @@
+{ stdenv, fetchFromGitHub, alsaLib, boost
+, qt4, libpulseaudio, codec2, libconfig
+, gnuradio, gr-osmosdr, gsm
+, libopus, libjpeg, protobuf, qwt, speex
+} :
+
+let
+  version = "0.5.0";
+
+in stdenv.mkDerivation {
+  pname = "qradiolink";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "kantooon";
+    repo = "qradiolink";
+    rev = version;
+    sha256 = "0xhg5zhjznmls5m3rhpk1qx0dipxmca12s85w15d0i7qwva2f1gi";
+  };
+
+  preBuild = ''
+    cd ext
+    protoc --cpp_out=. Mumble.proto
+    protoc --cpp_out=. QRadioLink.proto
+    cd ..
+    qmake
+  '';
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp qradiolink $out/bin
+  '';
+
+  buildInputs = [
+    qt4
+    alsaLib
+    boost
+    libpulseaudio
+    codec2
+    libconfig
+    gsm
+    gnuradio
+    gr-osmosdr
+    libopus
+    libjpeg
+    protobuf
+    speex
+    qwt
+  ];
+
+  enableParallelBuilding = true;
+
+  meta = with stdenv.lib; {
+    description = "SDR transceiver application for analog and digital modes";
+    homepage = "http://qradiolink.org/";
+    license = licenses.agpl3;
+    maintainers = [ maintainers.markuskowa ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/qsstv/default.nix b/nixpkgs/pkgs/applications/radio/qsstv/default.nix
new file mode 100644
index 000000000000..d5d12a714031
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/qsstv/default.nix
@@ -0,0 +1,36 @@
+{ mkDerivation, stdenv, fetchurl, qtbase, qmake, openjpeg, pkgconfig, fftw,
+  libpulseaudio, alsaLib, hamlib, libv4l, fftwFloat }:
+
+mkDerivation rec {
+  version = "9.4.4";
+  pname = "qsstv";
+
+  src = fetchurl {
+    url = "http://users.telenet.be/on4qz/qsstv/downloads/qsstv_${version}.tar.gz";
+    sha256 = "0f9hx6sy418cb23fadll298pqbc5l2lxsdivi4vgqbkvx7sw58zi";
+  };
+
+  enableParallelBuilding = true;
+
+  nativeBuildInputs = [
+    qmake
+    pkgconfig
+  ];
+
+  buildInputs = [ qtbase openjpeg fftw libpulseaudio alsaLib hamlib libv4l
+                  fftwFloat ];
+
+  postInstall = ''
+    # Install desktop icon
+    install -D qsstv/icons/qsstv.png $out/share/pixmaps/qsstv.png
+  '';
+
+  meta = with stdenv.lib; {
+    description = "Qt-based slow-scan TV and fax";
+    homepage = "http://users.telenet.be/on4qz/";
+    platforms = platforms.linux;
+    license = stdenv.lib.licenses.gpl3;
+    maintainers = with stdenv.lib.maintainers; [ hax404 ];
+  };
+}
+
diff --git a/nixpkgs/pkgs/applications/radio/rtl-ais/default.nix b/nixpkgs/pkgs/applications/radio/rtl-ais/default.nix
new file mode 100644
index 000000000000..f806f07d597d
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/rtl-ais/default.nix
@@ -0,0 +1,24 @@
+{ stdenv, fetchFromGitHub, pkgconfig, libusb1, rtl-sdr }:
+
+stdenv.mkDerivation {
+  name = "rtl-ais";
+  version = "0.8.1";
+  buildInputs = [ pkgconfig rtl-sdr libusb1 ];
+
+  src = fetchFromGitHub {
+    owner = "dgiardini";
+    repo = "rtl-ais";
+    rev = "0e85f4e5f9ce7378834c3129bc894580efc24291";
+    sha256 = "0wm4zai1vs89mf0zgz52q5w5rj8f3i3v6zg42hfb7aqabi25r3jf";
+  };
+
+  makeFlags = [ "PREFIX=$(out)" ];
+
+  meta = with stdenv.lib; {
+    description = "A simple AIS tuner and generic dual-frequency FM demodulator";
+    homepage = "https://github.com/dgiardini/rtl-ais";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ mgdm ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/rtl-sdr/default.nix b/nixpkgs/pkgs/applications/radio/rtl-sdr/default.nix
new file mode 100644
index 000000000000..8fb5154ff788
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/rtl-sdr/default.nix
@@ -0,0 +1,37 @@
+{ stdenv, fetchgit, cmake, pkgconfig, libusb1 }:
+
+stdenv.mkDerivation rec {
+  pname = "rtl-sdr";
+  version = "0.6.0";
+
+  src = fetchgit {
+    url = "git://git.osmocom.org/rtl-sdr.git";
+    rev = "refs/tags/${version}";
+    sha256 = "0lmvsnb4xw4hmz6zs0z5ilsah5hjz29g1s0050n59fllskqr3b8k";
+  };
+
+  nativeBuildInputs = [ pkgconfig cmake ];
+  buildInputs = [ libusb1 ];
+
+  # TODO: get these fixes upstream:
+  # * Building with -DINSTALL_UDEV_RULES=ON tries to install udev rules to
+  #   /etc/udev/rules.d/, and there is no option to install elsewhere. So install
+  #   rules manually.
+  # * Propagate libusb-1.0 dependency in pkg-config file.
+  postInstall = stdenv.lib.optionalString stdenv.isLinux ''
+    mkdir -p "$out/etc/udev/rules.d/"
+    cp ../rtl-sdr.rules "$out/etc/udev/rules.d/99-rtl-sdr.rules"
+
+    pcfile="$out"/lib/pkgconfig/librtlsdr.pc
+    grep -q "Requires:" "$pcfile" && { echo "Upstream has added 'Requires:' in $(basename "$pcfile"); update nix expression."; exit 1; }
+    echo "Requires: libusb-1.0" >> "$pcfile"
+  '';
+
+  meta = with stdenv.lib; {
+    description = "Turns your Realtek RTL2832 based DVB dongle into a SDR receiver";
+    homepage = "http://sdr.osmocom.org/trac/wiki/rtl-sdr";
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux ++ platforms.darwin;
+    maintainers = [ maintainers.bjornfor ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/rtl_433/default.nix b/nixpkgs/pkgs/applications/radio/rtl_433/default.nix
new file mode 100644
index 000000000000..78d0f8befc98
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/rtl_433/default.nix
@@ -0,0 +1,29 @@
+{ stdenv, fetchFromGitHub, autoreconfHook, pkgconfig
+, libusb1, rtl-sdr, soapysdr-with-plugins
+}:
+
+stdenv.mkDerivation {
+
+  version = "20.02";
+  pname = "rtl_433";
+
+  src = fetchFromGitHub {
+    owner = "merbanan";
+    repo = "rtl_433";
+    rev = "20.02";
+    sha256 = "11991xky9gawkragdyg27qsf7kw5bhlg7ygvf3fn7ng00x4xbh1z";
+  };
+
+  nativeBuildInputs = [ autoreconfHook pkgconfig ];
+
+  buildInputs = [ libusb1 rtl-sdr soapysdr-with-plugins ];
+
+  meta = with stdenv.lib; {
+    description = "Decode traffic from devices that broadcast on 433.9 MHz";
+    homepage = "https://github.com/merbanan/rtl_433";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ earldouglas ];
+    platforms = platforms.all;
+  };
+
+}
diff --git a/nixpkgs/pkgs/applications/radio/sdrangel/default.nix b/nixpkgs/pkgs/applications/radio/sdrangel/default.nix
new file mode 100644
index 000000000000..6d0a19334dec
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/sdrangel/default.nix
@@ -0,0 +1,76 @@
+{
+airspy,
+boost,
+cm256cc,
+cmake,
+codec2,
+fetchFromGitHub,
+fftwFloat,
+glew,
+hackrf,
+lib,
+libav,
+libiio,
+libopus,
+libpulseaudio,
+libusb-compat-0_1,
+limesuite,
+mkDerivation,
+ocl-icd,
+opencv3,
+pkgconfig,
+qtbase,
+qtmultimedia,
+qtwebsockets,
+rtl-sdr,
+serialdv
+}:
+
+let
+
+  codec2' = codec2.overrideAttrs (old: {
+    src = fetchFromGitHub {
+      owner = "drowe67";
+      repo = "codec2";
+      rev = "567346818c0d4d697773cf66d925fdb031e15668";
+      sha256 = "0ngqlh2cw5grx2lg7xj8baz6p55gfhq4caggxkb4pxlg817pwbpa";
+    };
+  });
+
+in mkDerivation rec {
+  pname = "sdrangel";
+  version = "4.11.12";
+
+  src = fetchFromGitHub {
+    owner = "f4exb";
+    repo = "sdrangel";
+    rev = "v${version}";
+    sha256 = "0zbx0gklylk8npb3wnnmqpam0pdxl40f20i3wzwwh4gqrppxywzx";
+    fetchSubmodules = false;
+  };
+
+  nativeBuildInputs = [ cmake pkgconfig ];
+  buildInputs = [
+    glew opencv3 libusb-compat-0_1 boost libopus limesuite libav libiio libpulseaudio
+    qtbase qtwebsockets qtmultimedia rtl-sdr airspy hackrf
+    fftwFloat codec2' cm256cc serialdv
+  ];
+  cmakeFlags = [
+    "-DLIBSERIALDV_INCLUDE_DIR:PATH=${serialdv}/include/serialdv"
+    "-DLIMESUITE_INCLUDE_DIR:PATH=${limesuite}/include"
+    "-DLIMESUITE_LIBRARY:FILEPATH=${limesuite}/lib/libLimeSuite.so"
+  ];
+
+  LD_LIBRARY_PATH = "${ocl-icd}/lib";
+
+  meta = with lib; {
+    description = "Software defined radio (SDR) software";
+    longDescription = ''
+        SDRangel is an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
+    '';
+    homepage = "https://github.com/f4exb/sdrangel";
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux;
+    maintainers = with maintainers; [ alkeryn ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/soapyairspy/default.nix b/nixpkgs/pkgs/applications/radio/soapyairspy/default.nix
new file mode 100644
index 000000000000..4a69e52741e7
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/soapyairspy/default.nix
@@ -0,0 +1,31 @@
+{ stdenv, fetchFromGitHub, cmake
+, airspy, soapysdr
+} :
+
+let
+  version = "0.1.2";
+
+in stdenv.mkDerivation {
+  pname = "soapyairspy";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "pothosware";
+    repo = "SoapyAirspy";
+    rev = "soapy-airspy-${version}";
+    sha256 = "061r77vs6ywxbxfif12y6v5xkz6gcvbz9k060q12vmdh6sisdwk2";
+  };
+
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [ airspy soapysdr ];
+
+  cmakeFlags = [ "-DSoapySDR_DIR=${soapysdr}/share/cmake/SoapySDR/" ];
+
+  meta = with stdenv.lib; {
+    homepage = "https://github.com/pothosware/SoapyAirspy";
+    description = "SoapySDR plugin for Airspy devices";
+    license = licenses.mit;
+    maintainers = with maintainers; [ markuskowa ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/soapybladerf/default.nix b/nixpkgs/pkgs/applications/radio/soapybladerf/default.nix
new file mode 100644
index 000000000000..7e2e17a84558
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/soapybladerf/default.nix
@@ -0,0 +1,32 @@
+{ stdenv, fetchFromGitHub, cmake, pkgconfig
+, libbladeRF, soapysdr
+} :
+
+let
+  version = "0.4.1";
+
+in stdenv.mkDerivation {
+  pname = "soapybladerf";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "pothosware";
+    repo = "SoapyBladeRF";
+    rev = "soapy-bladerf-${version}";
+    sha256 = "02wh09850vinqg248fw4lxmx7y857cqmnnb8jm9zhyrsggal0hki";
+  };
+
+  nativeBuildInputs = [ cmake pkgconfig ];
+  buildInputs = [ libbladeRF soapysdr ];
+
+  cmakeFlags = [ "-DSoapySDR_DIR=${soapysdr}/share/cmake/SoapySDR/" ];
+
+
+  meta = with stdenv.lib; {
+    homepage = "https://github.com/pothosware/SoapyBladeRF";
+    description = "SoapySDR plugin for BladeRF devices";
+    license = licenses.lgpl21;
+    maintainers = with maintainers; [ markuskowa ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/soapyhackrf/default.nix b/nixpkgs/pkgs/applications/radio/soapyhackrf/default.nix
new file mode 100644
index 000000000000..e472b1cc3ae9
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/soapyhackrf/default.nix
@@ -0,0 +1,31 @@
+{ stdenv, fetchFromGitHub, cmake, pkgconfig
+, hackrf, soapysdr
+} :
+
+let
+  version = "0.3.3";
+
+in stdenv.mkDerivation {
+  pname = "soapyhackrf";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "pothosware";
+    repo = "SoapyHackRF";
+    rev = "soapy-hackrf-${version}";
+    sha256 = "1awn89z462500gb3fjb7x61b1znkjri9n1d39bqfip1qk4s11pxc";
+  };
+
+  nativeBuildInputs = [ cmake pkgconfig ];
+  buildInputs = [ hackrf soapysdr ];
+
+  cmakeFlags = [ "-DSoapySDR_DIR=${soapysdr}/share/cmake/SoapySDR/" ];
+
+  meta = with stdenv.lib; {
+    homepage = "https://github.com/pothosware/SoapyHackRF";
+    description = "SoapySDR plugin for HackRF devices";
+    license = licenses.mit;
+    maintainers = with maintainers; [ markuskowa ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/soapyremote/default.nix b/nixpkgs/pkgs/applications/radio/soapyremote/default.nix
new file mode 100644
index 000000000000..ed94693db41f
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/soapyremote/default.nix
@@ -0,0 +1,29 @@
+{ stdenv, fetchFromGitHub, cmake, soapysdr, avahi }:
+
+let
+  version = "0.5.1";
+
+in stdenv.mkDerivation {
+  pname = "soapyremote";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "pothosware";
+    repo = "SoapyRemote";
+    rev = "soapy-remote-${version}";
+    sha256 = "1qlpjg8mh564q26mni8g6bb8w9nj7hgcq86278fszxpwpnk3jsvk";
+  };
+
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [ soapysdr avahi ];
+
+  cmakeFlags = [ "-DSoapySDR_DIR=${soapysdr}/share/cmake/SoapySDR/" ];
+
+  meta = with stdenv.lib; {
+    homepage = "https://github.com/pothosware/SoapyRemote";
+    description = "SoapySDR plugin for remote access to SDRs";
+    license = licenses.boost;
+    maintainers = with maintainers; [ markuskowa ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/soapyrtlsdr/default.nix b/nixpkgs/pkgs/applications/radio/soapyrtlsdr/default.nix
new file mode 100644
index 000000000000..8f342190ba7e
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/soapyrtlsdr/default.nix
@@ -0,0 +1,31 @@
+{ stdenv, fetchFromGitHub, cmake, pkgconfig
+, rtl-sdr, soapysdr
+} :
+
+let
+  version = "0.3.0";
+
+in stdenv.mkDerivation {
+  pname = "soapyrtlsdr";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "pothosware";
+    repo = "SoapyRTLSDR";
+    rev = "soapy-rtlsdr-${version}";
+    sha256 = "15j0s7apbg9cjr6rcbr058kl0r3szwzf00ixcbykxb77fh7c6r9w";
+  };
+
+  nativeBuildInputs = [ cmake pkgconfig ];
+  buildInputs = [ rtl-sdr soapysdr ];
+
+  cmakeFlags = [ "-DSoapySDR_DIR=${soapysdr}/share/cmake/SoapySDR/" ];
+
+  meta = with stdenv.lib; {
+    homepage = "https://github.com/pothosware/SoapyRTLSDR";
+    description = "SoapySDR plugin for RTL-SDR devices";
+    license = licenses.mit;
+    maintainers = with maintainers; [ ragge ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/soapysdr/default.nix b/nixpkgs/pkgs/applications/radio/soapysdr/default.nix
new file mode 100644
index 000000000000..676f7d3c839e
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/soapysdr/default.nix
@@ -0,0 +1,55 @@
+{ stdenv, lib, lndir, makeWrapper
+, fetchFromGitHub, cmake
+, libusb-compat-0_1, pkgconfig
+, usePython ? false
+, python, ncurses, swig2
+, extraPackages ? []
+} :
+
+let
+
+  version = "0.7.2";
+  modulesVersion = with lib; versions.major version + "." + versions.minor version;
+  modulesPath = "lib/SoapySDR/modules" + modulesVersion;
+  extraPackagesSearchPath = lib.makeSearchPath modulesPath extraPackages;
+
+in stdenv.mkDerivation {
+  pname = "soapysdr";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "pothosware";
+    repo = "SoapySDR";
+    rev = "soapy-sdr-${version}";
+    sha256 = "102wnpjxrwba20pzdh1vvx0yg1h8vqd8z914idxflg9p14r6v5am";
+  };
+
+  nativeBuildInputs = [ cmake makeWrapper pkgconfig ];
+  buildInputs = [ libusb-compat-0_1 ncurses ]
+    ++ lib.optionals usePython [ python swig2 ];
+
+  propagatedBuildInputs = lib.optional usePython python.pkgs.numpy;
+
+  cmakeFlags = [
+    "-DCMAKE_BUILD_TYPE=Release"
+  ] ++ lib.optional usePython "-DUSE_PYTHON_CONFIG=ON";
+
+  postFixup = lib.optionalString (lib.length extraPackages != 0) ''
+    # Join all plugins via symlinking
+    for i in ${toString extraPackages}; do
+      ${lndir}/bin/lndir -silent $i $out
+    done
+    # Needed for at least the remote plugin server
+    for file in $out/bin/*; do
+        wrapProgram "$file" --prefix SOAPY_SDR_PLUGIN_PATH : ${extraPackagesSearchPath}
+    done
+  '';
+
+  meta = with stdenv.lib; {
+    homepage = "https://github.com/pothosware/SoapySDR";
+    description = "Vendor and platform neutral SDR support library";
+    license = licenses.boost;
+    maintainers = with maintainers; [ markuskowa ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/soapyuhd/default.nix b/nixpkgs/pkgs/applications/radio/soapyuhd/default.nix
new file mode 100644
index 000000000000..a169116c29a1
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/soapyuhd/default.nix
@@ -0,0 +1,35 @@
+{ stdenv, fetchFromGitHub, cmake, pkgconfig
+, uhd, boost, soapysdr
+} :
+
+let
+  version = "0.3.6";
+
+in stdenv.mkDerivation {
+  pname = "soapyuhd";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "pothosware";
+    repo = "SoapyUHD";
+    rev = "soapy-uhd-${version}";
+    sha256 = "11kp5iv21k8lqwjjydzqmcxdgpm6yicw6d3jhzvcvwcavd41crs7";
+  };
+
+  nativeBuildInputs = [ cmake pkgconfig ];
+  buildInputs = [ uhd boost soapysdr ];
+
+  cmakeFlags = [ "-DSoapySDR_DIR=${soapysdr}/share/cmake/SoapySDR/" ];
+
+  postPatch = ''
+    sed -i "s:DESTINATION .*uhd/modules:DESTINATION $out/lib/uhd/modules:" CMakeLists.txt
+  '';
+
+  meta = with stdenv.lib; {
+    homepage = "https://github.com/pothosware/SoapyAirspy";
+    description = "SoapySDR plugin for UHD devices";
+    license = licenses.gpl3;
+    maintainers = with maintainers; [ markuskowa ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/svxlink/default.nix b/nixpkgs/pkgs/applications/radio/svxlink/default.nix
new file mode 100644
index 000000000000..e06fcb5d3e67
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/svxlink/default.nix
@@ -0,0 +1,71 @@
+{ stdenv, cmake, pkgconfig, fetchFromGitHub, makeDesktopItem, alsaLib, speex
+, libopus, curl, gsm, libgcrypt, libsigcxx, popt, qtbase, qttools
+, wrapQtAppsHook, rtl-sdr, tcl, doxygen, groff }:
+
+let
+  desktopItem = makeDesktopItem rec {
+    name = "Qtel";
+    exec = "qtel";
+    icon = "qtel";
+    desktopName = name;
+    genericName = "EchoLink Client";
+    categories = "HamRadio;Qt;Network;";
+  };
+
+in stdenv.mkDerivation rec {
+  pname = "svxlink";
+  version = "19.09.1";
+
+  src = fetchFromGitHub {
+    owner = "sm0svx";
+    repo = pname;
+    rev = version;
+    sha256 = "0xmbac821w9kl7imlz0mra19mlhi0rlpbyyay26w1y7h98j4g4yp";
+  };
+
+  cmakeFlags = [
+    "-DDO_INSTALL_CHOWN=NO"
+    "-DRTLSDR_LIBRARIES=${rtl-sdr}/lib/librtlsdr.so"
+    "-DRTLSDR_INCLUDE_DIRS=${rtl-sdr}/include"
+    "../src"
+  ];
+  enableParallelBuilding = true;
+  dontWrapQtApps = true;
+
+  nativeBuildInputs = [ cmake pkgconfig doxygen groff wrapQtAppsHook ];
+
+  buildInputs = [
+    alsaLib
+    curl
+    gsm
+    libgcrypt
+    libsigcxx
+    libopus
+    popt
+    qtbase
+    qttools
+    rtl-sdr
+    speex
+    tcl
+  ];
+
+  postInstall = ''
+    rm -f $out/share/applications/*
+    cp -v ${desktopItem}/share/applications/* $out/share/applications
+    mv $out/share/icons/link.xpm $out/share/icons/qtel.xpm
+
+    wrapQtApp $out/bin/qtel
+  '';
+
+  meta = with stdenv.lib; {
+    description = "Advanced repeater controller and EchoLink software";
+    longDescription = ''
+      Advanced repeater controller and EchoLink software for Linux including a
+      GUI, Qtel - The Qt EchoLink client
+    '';
+    homepage = "http://www.svxlink.org/";
+    license = with licenses; [ gpl2 ];
+    maintainers = with maintainers; [ zaninime ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/tlf/default.nix b/nixpkgs/pkgs/applications/radio/tlf/default.nix
new file mode 100644
index 000000000000..fd9ab82b321c
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/tlf/default.nix
@@ -0,0 +1,40 @@
+{ stdenv, fetchFromGitHub, autoreconfHook, autoconf, automake, pkgconfig, glib
+, perl, ncurses5, hamlib, xmlrpc_c }:
+
+stdenv.mkDerivation rec {
+  pname = "tlf";
+  version = "1.4.1";
+
+  src = fetchFromGitHub {
+    owner = pname;
+    repo = pname;
+    rev = "${pname}-${version}";
+    sha256 = "1xpgs4k27pjd9mianfknknp6mf34365bcp96wrv5xh4dhph573rj";
+  };
+
+  nativeBuildInputs = [ autoreconfHook autoconf automake pkgconfig perl ];
+  buildInputs = [ glib ncurses5 hamlib xmlrpc_c ];
+
+  configureFlags = [ "--enable-hamlib" "--enable-fldigi-xmlrpc" ];
+
+  postInstall = ''
+    mkdir -p $out/lib
+    ln -s ${ncurses5.out}/lib/libtinfo.so.5 $out/lib/libtinfo.so.5
+  '';
+
+  meta = with stdenv.lib; {
+    description = "Advanced ham radio logging and contest program";
+    longDescription = ''
+      TLF is a curses based console mode general logging and contest program for
+      amateur radio.
+
+      It supports the CQWW, the WPX, the ARRL-DX, the ARRL-FD, the PACC and the
+      EU SPRINT shortwave contests (single operator) as well as a LOT MORE basic
+      contests, general QSO and DXpedition mode.
+    '';
+    homepage = "https://tlf.github.io/";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ etu ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/tqsl/default.nix b/nixpkgs/pkgs/applications/radio/tqsl/default.nix
new file mode 100644
index 000000000000..fd5f5505a672
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/tqsl/default.nix
@@ -0,0 +1,30 @@
+{ stdenv, fetchurl, makeWrapper, cmake, expat, openssl, zlib, db, curl, wxGTK }:
+
+stdenv.mkDerivation rec {
+  pname = "tqsl";
+  version = "2.5.1";
+
+  src = fetchurl {
+    url = "https://www.arrl.org/files/file/LoTW%20Instructions/${pname}-${version}.tar.gz";
+    sha256 = "00v4n8pvi5qi2psjnrw611w5gg5bdlaxbsny535fsci3smyygpc0";
+  };
+
+  nativeBuildInputs = [ makeWrapper ];
+  buildInputs = [
+    cmake
+    expat
+    openssl
+    zlib
+    db
+    curl
+    wxGTK
+  ];
+
+  meta = with stdenv.lib; {
+    description = "Software for using the ARRL Logbook of the World";
+    homepage = "https://www.arrl.org/tqsl-download";
+    license = licenses.bsd3;
+    platforms = platforms.linux;
+    maintainers = [ maintainers.dpflug ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/uhd/default.nix b/nixpkgs/pkgs/applications/radio/uhd/default.nix
new file mode 100644
index 000000000000..e7ddb5787fac
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/uhd/default.nix
@@ -0,0 +1,160 @@
+{ stdenv
+, fetchurl
+, fetchFromGitHub
+, cmake
+, pkgconfig
+# See https://files.ettus.com/manual_archive/v3.15.0.0/html/page_build_guide.html for dependencies explanations
+, boost
+, enableLibuhd_C_api ? true
+# requires numpy
+, enableLibuhd_Python_api ? false
+, python3 ? null
+, enableExamples ? false
+, enableUtils ? false
+, enableLiberio ? false
+, liberio ? null
+, libusb1 ? null
+, enableDpdk ? false
+, dpdk ? null
+# Devices
+, enableOctoClock ? true
+, enableMpmd ? true
+, enableB100 ? true
+, enableB200 ? true
+, enableUsrp1 ? true
+, enableUsrp2 ? true
+, enableX300 ? true
+, enableN230 ? true
+, enableN300 ? true
+, enableN320 ? true
+, enableE300 ? true
+, enableE320 ? true
+}:
+
+let
+  onOffBool = b: if b then "ON" else "OFF";
+  inherit (stdenv.lib) optionals;
+in
+
+stdenv.mkDerivation rec {
+  pname = "uhd";
+  # UHD seems to use three different version number styles: x.y.z, xxx_yyy_zzz
+  # and xxx.yyy.zzz. Hrmpf... style keeps changing
+  version = "3.15.0.0";
+
+  src = fetchFromGitHub {
+    owner = "EttusResearch";
+    repo = "uhd";
+    rev = "v${version}";
+    sha256 = "0jknln88a69fh244670nb7qrflbyv0vvdxfddb5g8ncpb6hcg8qf";
+  };
+  # Firmware images are downloaded (pre-built) from the respective release on Github
+  uhdImagesSrc = fetchurl {
+    url = "https://github.com/EttusResearch/uhd/releases/download/v${version}/uhd-images_${version}.tar.xz";
+    sha256 = "1fir1a13ac07mqhm4sr34cixiqj2difxq0870qv1wr7a7cbfw6vp";
+  };
+
+  enableParallelBuilding = true;
+
+  cmakeFlags = [
+    "-DENABLE_LIBUHD=ON"
+    "-DENABLE_USB=ON"
+    "-DENABLE_TESTS=ON" # This installs tests as well so we delete them via postPhases
+    "-DENABLE_EXAMPLES=${onOffBool enableExamples}"
+    "-DENABLE_UTILS=${onOffBool enableUtils}"
+    "-DENABLE_LIBUHD_C_API=${onOffBool enableLibuhd_C_api}"
+    "-DENABLE_LIBUHD_PYTHON_API=${onOffBool enableLibuhd_Python_api}"
+    "-DENABLE_LIBERIO=${onOffBool enableLiberio}"
+    "-DENABLE_DPDK=${onOffBool enableDpdk}"
+    # Devices
+    "-DENABLE_OCTOCLOCK=${onOffBool enableOctoClock}"
+    "-DENABLE_MPMD=${onOffBool enableMpmd}"
+    "-DENABLE_B100=${onOffBool enableB100}"
+    "-DENABLE_B200=${onOffBool enableB200}"
+    "-DENABLE_USRP1=${onOffBool enableUsrp1}"
+    "-DENABLE_USRP2=${onOffBool enableUsrp2}"
+    "-DENABLE_X300=${onOffBool enableX300}"
+    "-DENABLE_N230=${onOffBool enableN230}"
+    "-DENABLE_N300=${onOffBool enableN300}"
+    "-DENABLE_N320=${onOffBool enableN320}"
+    "-DENABLE_E300=${onOffBool enableE300}"
+    "-DENABLE_E320=${onOffBool enableE320}"
+  ]
+    # TODO: Check if this still needed
+    # ABI differences GCC 7.1
+    # /nix/store/wd6r25miqbk9ia53pp669gn4wrg9n9cj-gcc-7.3.0/include/c++/7.3.0/bits/vector.tcc:394:7: note: parameter passing for argument of type 'std::vector<uhd::range_t>::iterator {aka __gnu_cxx::__normal_iterator<uhd::range_t*, std::vector<uhd::range_t> >}' changed in GCC 7.1
+    ++ [ (stdenv.lib.optionalString stdenv.isAarch32 "-DCMAKE_CXX_FLAGS=-Wno-psabi") ]
+  ;
+
+  # Python + Mako are always required for the build itself but not necessary for runtime.
+  pythonEnv = python3.withPackages (ps: with ps; [ Mako ]
+    ++ optionals (enableLibuhd_Python_api) [ numpy setuptools ]
+    ++ optionals (enableUtils) [ requests six ]
+  );
+
+  nativeBuildInputs = [
+    cmake
+    pkgconfig
+  ]
+    # If both enableLibuhd_Python_api and enableUtils are off, we don't need
+    # pythonEnv in buildInputs as it's a 'build' dependency and not a runtime
+    # dependency
+    ++ optionals (!enableLibuhd_Python_api && !enableUtils) [ pythonEnv ]
+  ;
+  buildInputs = [
+    boost
+    libusb1
+  ]
+    # However, if enableLibuhd_Python_api *or* enableUtils is on, we need
+    # pythonEnv for runtime as well. The utilities' runtime dependencies are
+    # handled at the environment
+    ++ optionals (enableLibuhd_Python_api || enableUtils) [ pythonEnv ]
+    ++ optionals (enableLiberio) [ liberio ]
+    ++ optionals (enableDpdk) [ dpdk ]
+  ;
+
+  doCheck = true;
+
+  # Build only the host software
+  preConfigure = "cd host";
+  # TODO: Check if this still needed, perhaps relevant:
+  # https://files.ettus.com/manual_archive/v3.15.0.0/html/page_build_guide.html#build_instructions_unix_arm
+  patches = if stdenv.isAarch32 then ./neon.patch else null;
+
+  postPhases = [ "installFirmware" "removeInstalledTests" ]
+    ++ optionals (enableUtils) [ "moveUdevRules" ]
+  ;
+
+  # UHD expects images in `$CMAKE_INSTALL_PREFIX/share/uhd/images`
+  installFirmware = ''
+    mkdir -p "$out/share/uhd/images"
+    tar --strip-components=1 -xvf "${uhdImagesSrc}" -C "$out/share/uhd/images"
+  '';
+
+  # -DENABLE_TESTS=ON installs the tests, we don't need them in the output
+  removeInstalledTests = ''
+    rm -r $out/lib/uhd/tests
+  '';
+
+  # Moves the udev rules to the standard location, needed only if utils are
+  # enabled
+  moveUdevRules = ''
+    mkdir -p $out/lib/udev/rules.d
+    mv $out/lib/uhd/utils/uhd-usrp.rules $out/lib/udev/rules.d/
+  '';
+
+  meta = with stdenv.lib; {
+    description = "USRP Hardware Driver (for Software Defined Radio)";
+    longDescription = ''
+      The USRP Hardware Driver (UHD) software is the hardware driver for all
+      USRP (Universal Software Radio Peripheral) devices.
+
+      USRP devices are designed and sold by Ettus Research, LLC and its parent
+      company, National Instruments.
+    '';
+    homepage = "https://uhd.ettus.com/";
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux ++ platforms.darwin;
+    maintainers = with maintainers; [ bjornfor fpletz tomberek ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/uhd/neon.patch b/nixpkgs/pkgs/applications/radio/uhd/neon.patch
new file mode 100644
index 000000000000..18ec59c1d64b
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/uhd/neon.patch
@@ -0,0 +1,19 @@
+Description: When building for armhf, enable NEON
+ NEON is part of the armhf baseline, so this will always be enabled on
+ armhf.
+Author: Paul Tagliamonte <paultag@debian.org>
+Bug-Debian: https://bugs.debian.org/873608
+Origin: vendor
+Last-Update: 2017-08-29
+
+--- uhd-3.10.2.0.orig/host/lib/convert/CMakeLists.txt
++++ uhd-3.10.2.0/host/lib/convert/CMakeLists.txt
+@@ -67,6 +67,8 @@ IF(HAVE_ARM_NEON_H AND (${CMAKE_SIZEOF_V
+         ${CMAKE_CURRENT_SOURCE_DIR}/convert_with_neon.cpp
+         ${CMAKE_CURRENT_SOURCE_DIR}/convert_neon.S
+     )
++
++    SET ( CMAKE_CXX_FLAGS "-mfpu=neon" )
+ ENDIF()
+ 
+ ########################################################################
diff --git a/nixpkgs/pkgs/applications/radio/unixcw/default.nix b/nixpkgs/pkgs/applications/radio/unixcw/default.nix
new file mode 100644
index 000000000000..fe31fd133e79
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/unixcw/default.nix
@@ -0,0 +1,37 @@
+{stdenv, fetchurl, libpulseaudio, alsaLib , pkgconfig, qt5}:
+stdenv.mkDerivation rec {
+  pname = "unixcw";
+  version = "3.5.1";
+  src = fetchurl {
+    url = "mirror://sourceforge/unixcw/unixcw_${version}.orig.tar.gz";
+    sha256 ="5f3aacd8a26e16e6eff437c7ae1e9b389956fb137eeb3de24670ce05de479e7a";
+  };
+  patches = [
+    ./remove-use-of-dlopen.patch
+  ];
+  buildInputs = [libpulseaudio alsaLib pkgconfig qt5.qtbase];
+  CFLAGS   ="-lasound -lpulse-simple";
+
+  meta = with stdenv.lib; {
+    description = "sound characters as Morse code on the soundcard or console speaker";
+    longDescription = ''
+       unixcw is a project providing libcw library and a set of programs
+       using the library: cw, cwgen, cwcp and xcwcp.
+       The programs are intended for people who want to learn receiving
+       and sending Morse code.
+       unixcw is developed and tested primarily on GNU/Linux system.
+
+       cw  reads  characters  from  an input file, or from standard input,
+       and sounds each valid character as Morse code on either the system sound card,
+       or the system console speaker.
+       After it sounds a  character, cw  echoes it to standard output.
+       The input stream can contain embedded command strings.
+       These change the parameters used when sounding the Morse code.
+       cw reports any errors in  embedded  commands
+     '';
+    homepage = "http://unixcw.sourceforge.net";
+    maintainers = [ maintainers.mafo ];
+    license = licenses.gpl2;
+    platforms=platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/unixcw/remove-use-of-dlopen.patch b/nixpkgs/pkgs/applications/radio/unixcw/remove-use-of-dlopen.patch
new file mode 100644
index 000000000000..0475c008ba22
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/unixcw/remove-use-of-dlopen.patch
@@ -0,0 +1,677 @@
+From e4b91b5a7943a3b54f555ff2e0029b83bd96b131 Mon Sep 17 00:00:00 2001
+From: MarcFontaine <MarcFontaine@users.noreply.github.com>
+Date: Sat, 9 Jun 2018 11:02:11 +0200
+Subject: [PATCH] remove use of dlopen
+
+---
+ src/libcw/libcw_alsa.c | 215 ++++++++++---------------------------------------
+ src/libcw/libcw_pa.c   | 118 ++++-----------------------
+ 2 files changed, 56 insertions(+), 277 deletions(-)
+
+diff --git a/src/libcw/libcw_alsa.c b/src/libcw/libcw_alsa.c
+index a669c6e..17c306d 100644
+--- a/src/libcw/libcw_alsa.c
++++ b/src/libcw/libcw_alsa.c
+@@ -35,7 +35,6 @@
+ 
+ 
+ 
+-#include <dlfcn.h> /* dlopen() and related symbols */
+ #include <alsa/asoundlib.h>
+ 
+ 
+@@ -65,7 +64,6 @@ static const snd_pcm_format_t CW_ALSA_SAMPLE_FORMAT = SND_PCM_FORMAT_S16; /* "Si
+ 
+ 
+ static int  cw_alsa_set_hw_params_internal(cw_gen_t *gen, snd_pcm_hw_params_t *params);
+-static int  cw_alsa_dlsym_internal(void *handle);
+ static int  cw_alsa_write_internal(cw_gen_t *gen);
+ static int  cw_alsa_debug_evaluate_write_internal(cw_gen_t *gen, int rv);
+ static int  cw_alsa_open_device_internal(cw_gen_t *gen);
+@@ -80,56 +78,6 @@ static int  cw_alsa_print_params_internal(snd_pcm_hw_params_t *hw_params);
+ 
+ 
+ 
+-static struct {
+-	void *handle;
+-
+-	int (* snd_pcm_open)(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode);
+-	int (* snd_pcm_close)(snd_pcm_t *pcm);
+-	int (* snd_pcm_prepare)(snd_pcm_t *pcm);
+-	int (* snd_pcm_drop)(snd_pcm_t *pcm);
+-	snd_pcm_sframes_t (* snd_pcm_writei)(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+-
+-	const char *(* snd_strerror)(int errnum);
+-
+-	int (* snd_pcm_hw_params_malloc)(snd_pcm_hw_params_t **ptr);
+-	int (* snd_pcm_hw_params_any)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+-	int (* snd_pcm_hw_params_set_format)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
+-	int (* snd_pcm_hw_params_set_rate_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+-	int (* snd_pcm_hw_params_set_access)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t _access);
+-	int (* snd_pcm_hw_params_set_channels)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
+-	int (* snd_pcm_hw_params)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+-	int (* snd_pcm_hw_params_get_periods)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+-	int (* snd_pcm_hw_params_get_period_size)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir);
+-	int (* snd_pcm_hw_params_get_period_size_min)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir);
+-	int (* snd_pcm_hw_params_get_buffer_size)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
+-} cw_alsa = {
+-	.handle = NULL,
+-
+-	.snd_pcm_open = NULL,
+-	.snd_pcm_close = NULL,
+-	.snd_pcm_prepare = NULL,
+-	.snd_pcm_drop = NULL,
+-	.snd_pcm_writei = NULL,
+-
+-	.snd_strerror = NULL,
+-
+-	.snd_pcm_hw_params_malloc = NULL,
+-	.snd_pcm_hw_params_any = NULL,
+-	.snd_pcm_hw_params_set_format = NULL,
+-	.snd_pcm_hw_params_set_rate_near = NULL,
+-	.snd_pcm_hw_params_set_access = NULL,
+-	.snd_pcm_hw_params_set_channels = NULL,
+-	.snd_pcm_hw_params = NULL,
+-	.snd_pcm_hw_params_get_periods = NULL,
+-	.snd_pcm_hw_params_get_period_size = NULL,
+-	.snd_pcm_hw_params_get_period_size_min = NULL,
+-	.snd_pcm_hw_params_get_buffer_size = NULL
+-};
+-
+-
+-
+-
+-
+ 
+ /**
+    \brief Check if it is possible to open ALSA output
+@@ -144,34 +92,19 @@ static struct {
+ */
+ bool cw_is_alsa_possible(const char *device)
+ {
+-	const char *library_name = "libasound.so.2";
+-	if (!cw_dlopen_internal(library_name, &(cw_alsa.handle))) {
+-		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "cw_alsa: can't access ALSA library \"%s\"", library_name);
+-		return false;
+-	}
+-
+-	int rv = cw_alsa_dlsym_internal(cw_alsa.handle);
+-	if (rv < 0) {
+-		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "cw_alsa: failed to resolve ALSA symbol #%d, can't correctly load ALSA library", rv);
+-		dlclose(cw_alsa.handle);
+-		return false;
+-	}
+-
+-	const char *dev = device ? device : CW_DEFAULT_ALSA_DEVICE;
++        int rv;
++        const char *dev = device ? device : CW_DEFAULT_ALSA_DEVICE;
+ 	snd_pcm_t *alsa_handle;
+-	rv = cw_alsa.snd_pcm_open(&alsa_handle,
++	rv = snd_pcm_open(&alsa_handle,
+ 				  dev,                     /* name */
+ 				  SND_PCM_STREAM_PLAYBACK, /* stream (playback/capture) */
+ 				  0);                      /* mode, 0 | SND_PCM_NONBLOCK | SND_PCM_ASYNC */
+ 	if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+ 			      "cw_alsa: can't open ALSA device \"%s\"", dev);
+-		dlclose(cw_alsa.handle);
+ 		return false;
+ 	} else {
+-		cw_alsa.snd_pcm_close(alsa_handle);
++		snd_pcm_close(alsa_handle);
+ 		return true;
+ 	}
+ }
+@@ -204,7 +137,7 @@ int cw_alsa_write_internal(cw_gen_t *gen)
+ 	/* Send audio buffer to ALSA.
+ 	   Size of correct and current data in the buffer is the same as
+ 	   ALSA's period, so there should be no underruns */
+-	int rv = cw_alsa.snd_pcm_writei(gen->alsa_data.handle, gen->buffer, gen->buffer_n_samples);
++	int rv = snd_pcm_writei(gen->alsa_data.handle, gen->buffer, gen->buffer_n_samples);
+ 	cw_alsa_debug_evaluate_write_internal(gen, rv);
+ 	/*
+ 	cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_INFO,
+@@ -231,7 +164,7 @@ int cw_alsa_write_internal(cw_gen_t *gen)
+ */
+ int cw_alsa_open_device_internal(cw_gen_t *gen)
+ {
+-	int rv = cw_alsa.snd_pcm_open(&gen->alsa_data.handle,
++	int rv = snd_pcm_open(&gen->alsa_data.handle,
+ 				      gen->audio_device,       /* name */
+ 				      SND_PCM_STREAM_PLAYBACK, /* stream (playback/capture) */
+ 				      0);                      /* mode, 0 | SND_PCM_NONBLOCK | SND_PCM_ASYNC */
+@@ -251,7 +184,7 @@ int cw_alsa_open_device_internal(cw_gen_t *gen)
+ 	/* TODO: move this to cw_alsa_set_hw_params_internal(),
+ 	   deallocate hw_params */
+ 	snd_pcm_hw_params_t *hw_params = NULL;
+-	rv = cw_alsa.snd_pcm_hw_params_malloc(&hw_params);
++	rv = snd_pcm_hw_params_malloc(&hw_params);
+ 	if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+ 			      "cw_alsa: can't allocate memory for ALSA hw params");
+@@ -265,7 +198,7 @@ int cw_alsa_open_device_internal(cw_gen_t *gen)
+ 		return CW_FAILURE;
+ 	}
+ 
+-	rv = cw_alsa.snd_pcm_prepare(gen->alsa_data.handle);
++	rv = snd_pcm_prepare(gen->alsa_data.handle);
+ 	if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+ 			      "cw_alsa: can't prepare ALSA handler");
+@@ -275,7 +208,7 @@ int cw_alsa_open_device_internal(cw_gen_t *gen)
+ 	/* Get size for data buffer */
+ 	snd_pcm_uframes_t frames; /* period size in frames */
+ 	int dir = 1;
+-	rv = cw_alsa.snd_pcm_hw_params_get_period_size_min(hw_params, &frames, &dir);
++	rv = snd_pcm_hw_params_get_period_size_min(hw_params, &frames, &dir);
+ 	cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_INFO,
+ 		      "cw_alsa: rv = %d, ALSA buffer size would be %u frames", rv, (unsigned int) frames);
+ 
+@@ -305,14 +238,11 @@ int cw_alsa_open_device_internal(cw_gen_t *gen)
+ void cw_alsa_close_device_internal(cw_gen_t *gen)
+ {
+ 	/* "Stop a PCM dropping pending frames. " */
+-	cw_alsa.snd_pcm_drop(gen->alsa_data.handle);
+-	cw_alsa.snd_pcm_close(gen->alsa_data.handle);
++	snd_pcm_drop(gen->alsa_data.handle);
++	snd_pcm_close(gen->alsa_data.handle);
+ 
+ 	gen->audio_device_is_open = false;
+ 
+-	if (cw_alsa.handle) {
+-		dlclose(cw_alsa.handle);
+-	}
+ 
+ #if CW_DEV_RAW_SINK
+ 	if (gen->dev_raw_sink != -1) {
+@@ -332,11 +262,11 @@ int cw_alsa_debug_evaluate_write_internal(cw_gen_t *gen, int rv)
+ 	if (rv == -EPIPE) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_WARNING,
+ 			      "cw_alsa: underrun");
+-		cw_alsa.snd_pcm_prepare(gen->alsa_data.handle);
++		snd_pcm_prepare(gen->alsa_data.handle);
+ 	} else if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_WARNING,
+-			      "cw_alsa: writei: %s", cw_alsa.snd_strerror(rv));
+-		cw_alsa.snd_pcm_prepare(gen->alsa_data.handle);
++			      "cw_alsa: writei: %s", snd_strerror(rv));
++		snd_pcm_prepare(gen->alsa_data.handle);
+ 	} else if (rv != gen->buffer_n_samples) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_WARNING,
+ 			      "cw_alsa: short write, %d != %d", rv, gen->buffer_n_samples);
+@@ -363,19 +293,19 @@ int cw_alsa_debug_evaluate_write_internal(cw_gen_t *gen, int rv)
+ int cw_alsa_set_hw_params_internal(cw_gen_t *gen, snd_pcm_hw_params_t *hw_params)
+ {
+ 	/* Get current hw configuration. */
+-	int rv = cw_alsa.snd_pcm_hw_params_any(gen->alsa_data.handle, hw_params);
++	int rv = snd_pcm_hw_params_any(gen->alsa_data.handle, hw_params);
+ 	if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "cw_alsa: get current hw params: %s", cw_alsa.snd_strerror(rv));
++			      "cw_alsa: get current hw params: %s", snd_strerror(rv));
+ 		return CW_FAILURE;
+ 	}
+ 
+ 
+ 	/* Set the sample format */
+-	rv = cw_alsa.snd_pcm_hw_params_set_format(gen->alsa_data.handle, hw_params, CW_ALSA_SAMPLE_FORMAT);
++	rv = snd_pcm_hw_params_set_format(gen->alsa_data.handle, hw_params, CW_ALSA_SAMPLE_FORMAT);
+ 	if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "cw_alsa: can't set sample format: %s", cw_alsa.snd_strerror(rv));
++			      "cw_alsa: can't set sample format: %s", snd_strerror(rv));
+ 		return CW_FAILURE;
+ 	}
+ 
+@@ -387,7 +317,7 @@ int cw_alsa_set_hw_params_internal(cw_gen_t *gen, snd_pcm_hw_params_t *hw_params
+ 	bool success = false;
+ 	for (int i = 0; cw_supported_sample_rates[i]; i++) {
+ 		rate = cw_supported_sample_rates[i];
+-		int rv = cw_alsa.snd_pcm_hw_params_set_rate_near(gen->alsa_data.handle, hw_params, &rate, &dir);
++		int rv = snd_pcm_hw_params_set_rate_near(gen->alsa_data.handle, hw_params, &rate, &dir);
+ 		if (!rv) {
+ 			if (rate != cw_supported_sample_rates[i]) {
+ 				cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_WARNING, "cw_alsa: imprecise sample rate:");
+@@ -402,7 +332,7 @@ int cw_alsa_set_hw_params_internal(cw_gen_t *gen, snd_pcm_hw_params_t *hw_params
+ 
+ 	if (!success) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "cw_alsa: can't get sample rate: %s", cw_alsa.snd_strerror(rv));
++			      "cw_alsa: can't get sample rate: %s", snd_strerror(rv));
+ 		return CW_FAILURE;
+         } else {
+ 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_INFO,
+@@ -410,18 +340,18 @@ int cw_alsa_set_hw_params_internal(cw_gen_t *gen, snd_pcm_hw_params_t *hw_params
+ 	}
+ 
+ 	/* Set PCM access type */
+-	rv = cw_alsa.snd_pcm_hw_params_set_access(gen->alsa_data.handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
++	rv = snd_pcm_hw_params_set_access(gen->alsa_data.handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
+ 	if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "cw_alsa: can't set access type: %s", cw_alsa.snd_strerror(rv));
++			      "cw_alsa: can't set access type: %s", snd_strerror(rv));
+ 		return CW_FAILURE;
+ 	}
+ 
+ 	/* Set number of channels */
+-	rv = cw_alsa.snd_pcm_hw_params_set_channels(gen->alsa_data.handle, hw_params, CW_AUDIO_CHANNELS);
++	rv = snd_pcm_hw_params_set_channels(gen->alsa_data.handle, hw_params, CW_AUDIO_CHANNELS);
+ 	if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "cw_alsa: can't set number of channels: %s", cw_alsa.snd_strerror(rv));
++			      "cw_alsa: can't set number of channels: %s", snd_strerror(rv));
+ 		return CW_FAILURE;
+ 	}
+ 
+@@ -496,7 +426,7 @@ int cw_alsa_set_hw_params_internal(cw_gen_t *gen, snd_pcm_hw_params_t *hw_params
+ 		snd_pcm_uframes_t accepted = 0; /* buffer size in frames  */
+ 		dir = 0;
+ 		for (snd_pcm_uframes_t val = 0; val < 10000; val++) {
+-			rv = cw_alsa.snd_pcm_hw_params_test_buffer_size(gen->alsa_data.handle, hw_params, val);
++			rv = snd_pcm_hw_params_test_buffer_size(gen->alsa_data.handle, hw_params, val);
+ 			if (rv == 0) {
+ 				cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_INFO,
+ 					      "cw_alsa: accepted buffer size: %u", (unsigned int) accepted);
+@@ -507,10 +437,10 @@ int cw_alsa_set_hw_params_internal(cw_gen_t *gen, snd_pcm_hw_params_t *hw_params
+ 		}
+ 
+ 		if (accepted > 0) {
+-			rv = cw_alsa.snd_pcm_hw_params_set_buffer_size(gen->alsa_data.handle, hw_params, accepted);
++			rv = snd_pcm_hw_params_set_buffer_size(gen->alsa_data.handle, hw_params, accepted);
+ 			if (rv < 0) {
+ 				cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-					      "cw_alsa: can't set accepted buffer size %u: %s", (unsigned int) accepted, cw_alsa.snd_strerror(rv));
++					      "cw_alsa: can't set accepted buffer size %u: %s", (unsigned int) accepted, snd_strerror(rv));
+ 			}
+ 		} else {
+ 			cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+@@ -526,7 +456,7 @@ int cw_alsa_set_hw_params_internal(cw_gen_t *gen, snd_pcm_hw_params_t *hw_params
+ 		/* this limit should be enough, "accepted" on my machine is 8 */
+ 		const unsigned int n_periods_max = 30;
+ 		for (unsigned int val = 1; val < n_periods_max; val++) {
+-			rv = cw_alsa.snd_pcm_hw_params_test_periods(gen->alsa_data.handle, hw_params, val, dir);
++			rv = snd_pcm_hw_params_test_periods(gen->alsa_data.handle, hw_params, val, dir);
+ 			if (rv == 0) {
+ 				accepted = val;
+ 				cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_INFO,
+@@ -534,10 +464,10 @@ int cw_alsa_set_hw_params_internal(cw_gen_t *gen, snd_pcm_hw_params_t *hw_params
+ 			}
+ 		}
+ 		if (accepted > 0) {
+-			rv = cw_alsa.snd_pcm_hw_params_set_periods(gen->alsa_data.handle, hw_params, accepted, dir);
++			rv = snd_pcm_hw_params_set_periods(gen->alsa_data.handle, hw_params, accepted, dir);
+ 			if (rv < 0) {
+ 				cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-					      "cw_alsa: can't set accepted number of periods %d: %s", accepted, cw_alsa.snd_strerror(rv));
++					      "cw_alsa: can't set accepted number of periods %d: %s", accepted, snd_strerror(rv));
+ 			}
+ 		} else {
+ 			cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+@@ -549,7 +479,7 @@ int cw_alsa_set_hw_params_internal(cw_gen_t *gen, snd_pcm_hw_params_t *hw_params
+ 		/* Test period size */
+ 		dir = 0;
+ 		for (snd_pcm_uframes_t val = 0; val < 100000; val++) {
+-			rv = cw_alsa.snd_pcm_hw_params_test_period_size(gen->alsa_data.handle, hw_params, val, dir);
++			rv = snd_pcm_hw_params_test_period_size(gen->alsa_data.handle, hw_params, val, dir);
+ 			if (rv == 0) {
+ 				cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_INFO,
+ 					      "cw_alsa: accepted period size: %lu", val);
+@@ -562,7 +492,7 @@ int cw_alsa_set_hw_params_internal(cw_gen_t *gen, snd_pcm_hw_params_t *hw_params
+ 		/* Test buffer time */
+ 		dir = 0;
+ 		for (unsigned int val = 0; val < 100000; val++) {
+-			rv = cw_alsa.snd_pcm_hw_params_test_buffer_time(gen->alsa_data.handle, hw_params, val, dir);
++			rv = snd_pcm_hw_params_test_buffer_time(gen->alsa_data.handle, hw_params, val, dir);
+ 			if (rv == 0) {
+ 				cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_INFO,
+ 					      "cw_alsa: accepted buffer time: %d", val);
+@@ -573,10 +503,10 @@ int cw_alsa_set_hw_params_internal(cw_gen_t *gen, snd_pcm_hw_params_t *hw_params
+ #endif /* #if CW_ALSA_HW_BUFFER_CONFIG */
+ 
+ 	/* Save hw parameters to device */
+-	rv = cw_alsa.snd_pcm_hw_params(gen->alsa_data.handle, hw_params);
++	rv = snd_pcm_hw_params(gen->alsa_data.handle, hw_params);
+ 	if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "cw_alsa: can't save hw parameters: %s", cw_alsa.snd_strerror(rv));
++			      "cw_alsa: can't save hw parameters: %s", snd_strerror(rv));
+ 		return CW_FAILURE;
+ 	} else {
+ 		return CW_SUCCESS;
+@@ -600,30 +530,30 @@ int cw_alsa_print_params_internal(snd_pcm_hw_params_t *hw_params)
+ 	unsigned int val = 0;
+ 	int dir = 0;
+ 
+-	int rv = cw_alsa.snd_pcm_hw_params_get_periods(hw_params, &val, &dir);
++	int rv = snd_pcm_hw_params_get_periods(hw_params, &val, &dir);
+ 	if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "cw_alsa: can't get 'periods': %s", cw_alsa.snd_strerror(rv));
++			      "cw_alsa: can't get 'periods': %s", snd_strerror(rv));
+ 	} else {
+ 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_INFO,
+ 			      "cw_alsa: 'periods' = %u", val);
+ 	}
+ 
+ 	snd_pcm_uframes_t period_size = 0;
+-	rv = cw_alsa.snd_pcm_hw_params_get_period_size(hw_params, &period_size, &dir);
++	rv = snd_pcm_hw_params_get_period_size(hw_params, &period_size, &dir);
+ 	if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "cw_alsa: can't get 'period size': %s", cw_alsa.snd_strerror(rv));
++			      "cw_alsa: can't get 'period size': %s", snd_strerror(rv));
+ 	} else {
+ 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_INFO,
+ 			      "cw_alsa: 'period size' = %u", (unsigned int) period_size);
+ 	}
+ 
+ 	snd_pcm_uframes_t buffer_size;
+-	rv = cw_alsa.snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size);
++	rv = snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size);
+ 	if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "cw_alsa: can't get buffer size: %s", cw_alsa.snd_strerror(rv));
++			      "cw_alsa: can't get buffer size: %s", snd_strerror(rv));
+ 	} else {
+ 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_INFO,
+ 			      "cw_alsa: 'buffer size' = %u", (unsigned int) buffer_size);
+@@ -642,70 +572,9 @@ int cw_alsa_print_params_internal(snd_pcm_hw_params_t *hw_params)
+ 
+ 
+ 
+-/**
+-   \brief Resolve/get symbols from ALSA library
+-
+-   Function resolves/gets addresses of few ALSA functions used by
+-   libcw and stores them in cw_alsa global variable.
+-
+-   On failure the function returns negative value, different for every
+-   symbol that the funciton failed to resolve. Function stops and returns
+-   on first failure.
+-
+-   \param handle - handle to open ALSA library
+-
+-   \return 0 on success
+-   \return negative value on failure
+-*/
+-static int cw_alsa_dlsym_internal(void *handle)
+-{
+-	*(void **) &(cw_alsa.snd_pcm_open)    = dlsym(handle, "snd_pcm_open");
+-	if (!cw_alsa.snd_pcm_open)    return -1;
+-	*(void **) &(cw_alsa.snd_pcm_close)   = dlsym(handle, "snd_pcm_close");
+-	if (!cw_alsa.snd_pcm_close)   return -2;
+-	*(void **) &(cw_alsa.snd_pcm_prepare) = dlsym(handle, "snd_pcm_prepare");
+-	if (!cw_alsa.snd_pcm_prepare) return -3;
+-	*(void **) &(cw_alsa.snd_pcm_drop)    = dlsym(handle, "snd_pcm_drop");
+-	if (!cw_alsa.snd_pcm_drop)    return -4;
+-	*(void **) &(cw_alsa.snd_pcm_writei)  = dlsym(handle, "snd_pcm_writei");
+-	if (!cw_alsa.snd_pcm_writei)  return -5;
+-
+-	*(void **) &(cw_alsa.snd_strerror) = dlsym(handle, "snd_strerror");
+-	if (!cw_alsa.snd_strerror) return -10;
+-
+-	*(void **) &(cw_alsa.snd_pcm_hw_params_malloc)               = dlsym(handle, "snd_pcm_hw_params_malloc");
+-	if (!cw_alsa.snd_pcm_hw_params_malloc)              return -20;
+-	*(void **) &(cw_alsa.snd_pcm_hw_params_any)                  = dlsym(handle, "snd_pcm_hw_params_any");
+-	if (!cw_alsa.snd_pcm_hw_params_any)                 return -21;
+-	*(void **) &(cw_alsa.snd_pcm_hw_params_set_format)           = dlsym(handle, "snd_pcm_hw_params_set_format");
+-	if (!cw_alsa.snd_pcm_hw_params_set_format)          return -22;
+-	*(void **) &(cw_alsa.snd_pcm_hw_params_set_rate_near)        = dlsym(handle, "snd_pcm_hw_params_set_rate_near");
+-	if (!cw_alsa.snd_pcm_hw_params_set_rate_near)       return -23;
+-	*(void **) &(cw_alsa.snd_pcm_hw_params_set_access)           = dlsym(handle, "snd_pcm_hw_params_set_access");
+-	if (!cw_alsa.snd_pcm_hw_params_set_access)          return -24;
+-	*(void **) &(cw_alsa.snd_pcm_hw_params_set_channels)         = dlsym(handle, "snd_pcm_hw_params_set_channels");
+-	if (!cw_alsa.snd_pcm_hw_params_set_channels)        return -25;
+-	*(void **) &(cw_alsa.snd_pcm_hw_params)                      = dlsym(handle, "snd_pcm_hw_params");
+-	if (!cw_alsa.snd_pcm_hw_params)                     return -26;
+-	*(void **) &(cw_alsa.snd_pcm_hw_params_get_periods)          = dlsym(handle, "snd_pcm_hw_params_get_periods");
+-	if (!cw_alsa.snd_pcm_hw_params_get_periods)         return -27;
+-	*(void **) &(cw_alsa.snd_pcm_hw_params_get_period_size)      = dlsym(handle, "snd_pcm_hw_params_get_period_size");
+-	if (!cw_alsa.snd_pcm_hw_params_get_period_size)     return -28;
+-	*(void **) &(cw_alsa.snd_pcm_hw_params_get_period_size_min)  = dlsym(handle, "snd_pcm_hw_params_get_period_size_min");
+-	if (!cw_alsa.snd_pcm_hw_params_get_period_size_min) return -29;
+-	*(void **) &(cw_alsa.snd_pcm_hw_params_get_buffer_size)      = dlsym(handle, "snd_pcm_hw_params_get_buffer_size");
+-	if (!cw_alsa.snd_pcm_hw_params_get_buffer_size)     return -30;
+-
+-	return 0;
+-}
+-
+-
+-
+-
+-
+ void cw_alsa_drop(cw_gen_t *gen)
+ {
+-	cw_alsa.snd_pcm_drop(gen->alsa_data.handle);
++	snd_pcm_drop(gen->alsa_data.handle);
+ 
+ 	return;
+ }
+@@ -721,7 +590,7 @@ void cw_alsa_drop(cw_gen_t *gen)
+ 
+ 
+ #include <stdbool.h>
+-#include "libcw_alsa.h"
++#include "libh"
+ 
+ 
+ 
+diff --git a/src/libcw/libcw_pa.c b/src/libcw/libcw_pa.c
+index 8269e9d..e190200 100644
+--- a/src/libcw/libcw_pa.c
++++ b/src/libcw/libcw_pa.c
+@@ -39,7 +39,6 @@
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <stdbool.h>
+-#include <dlfcn.h> /* dlopen() and related symbols */
+ #include <string.h>
+ #include <assert.h>
+ #include <sys/types.h>
+@@ -63,39 +62,12 @@ extern cw_debug_t cw_debug_object_dev;
+ 
+ 
+ static pa_simple *cw_pa_simple_new_internal(pa_sample_spec *ss, pa_buffer_attr *ba, const char *device, const char *stream_name, int *error);
+-static int        cw_pa_dlsym_internal(void *handle);
+ static int        cw_pa_open_device_internal(cw_gen_t *gen);
+ static void       cw_pa_close_device_internal(cw_gen_t *gen);
+ static int        cw_pa_write_internal(cw_gen_t *gen);
+ 
+ 
+ 
+-static struct {
+-	void *handle;
+-
+-	pa_simple *(* pa_simple_new)(const char *server, const char *name, pa_stream_direction_t dir, const char *dev, const char *stream_name, const pa_sample_spec *ss, const pa_channel_map *map, const pa_buffer_attr *attr, int *error);
+-	void       (* pa_simple_free)(pa_simple *s);
+-	int        (* pa_simple_write)(pa_simple *s, const void *data, size_t bytes, int *error);
+-	pa_usec_t  (* pa_simple_get_latency)(pa_simple *s, int *error);
+-	int        (* pa_simple_drain)(pa_simple *s, int *error);
+-
+-	size_t     (* pa_usec_to_bytes)(pa_usec_t t, const pa_sample_spec *spec);
+-	char      *(* pa_strerror)(int error);
+-} cw_pa = {
+-	.handle = NULL,
+-
+-	.pa_simple_new = NULL,
+-	.pa_simple_free = NULL,
+-	.pa_simple_write = NULL,
+-	.pa_simple_get_latency = NULL,
+-	.pa_simple_drain = NULL,
+-
+-	.pa_usec_to_bytes = NULL,
+-	.pa_strerror = NULL
+-};
+-
+-
+-
+ 
+ static const pa_sample_format_t CW_PA_SAMPLE_FORMAT = PA_SAMPLE_S16LE; /* Signed 16 bit, Little Endian */
+ static const int CW_PA_BUFFER_N_SAMPLES = 1024;
+@@ -117,21 +89,6 @@ static const int CW_PA_BUFFER_N_SAMPLES = 1024;
+ */
+ bool cw_is_pa_possible(const char *device)
+ {
+-	const char *library_name = "libpulse-simple.so";
+-	if (!cw_dlopen_internal(library_name, &(cw_pa.handle))) {
+-		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "libcw_pa: can't access PulseAudio library \"%s\"", library_name);
+-		return false;
+-	}
+-
+-	int rv = cw_pa_dlsym_internal(cw_pa.handle);
+-	if (rv < 0) {
+-		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "libcw_pa: failed to resolve PulseAudio symbol #%d, can't correctly load PulseAudio library", rv);
+-		dlclose(cw_pa.handle);
+-		return false;
+-	}
+-
+ 	const char *dev = (char *) NULL;
+ 	if (device && strcmp(device, CW_DEFAULT_PA_DEVICE)) {
+ 		dev = device;
+@@ -145,13 +102,10 @@ bool cw_is_pa_possible(const char *device)
+ 
+ 	if (!s) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "libcw_pa: can't connect to PulseAudio server: %s", cw_pa.pa_strerror(error));
+-		if (cw_pa.handle) {
+-			dlclose(cw_pa.handle);
+-		}
++			      "libcw_pa: can't connect to PulseAudio server: %s", pa_strerror(error));
+ 		return false;
+ 	} else {
+-		cw_pa.pa_simple_free(s);
++		pa_simple_free(s);
+ 		s = NULL;
+ 		return true;
+ 	}
+@@ -186,10 +140,10 @@ int cw_pa_write_internal(cw_gen_t *gen)
+ 
+ 	int error = 0;
+ 	size_t n_bytes = sizeof (gen->buffer[0]) * gen->buffer_n_samples;
+-	int rv = cw_pa.pa_simple_write(gen->pa_data.s, gen->buffer, n_bytes, &error);
++	int rv = pa_simple_write(gen->pa_data.s, gen->buffer, n_bytes, &error);
+ 	if (rv < 0) {
+ 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "libcw_pa: pa_simple_write() failed: %s", cw_pa.pa_strerror(error));
++			      "libcw_pa: pa_simple_write() failed: %s", pa_strerror(error));
+ 	} else {
+ 		//cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_INFO, "libcw_pa: written %d samples with PulseAudio", gen->buffer_n_samples);
+ 	}
+@@ -237,13 +191,13 @@ pa_simple *cw_pa_simple_new_internal(pa_sample_spec *ss, pa_buffer_attr *ba, con
+ 	}
+ 
+ 	// http://www.mail-archive.com/pulseaudio-tickets@mail.0pointer.de/msg03295.html
+-	ba->tlength = cw_pa.pa_usec_to_bytes(50*1000, ss);
+-	ba->minreq = cw_pa.pa_usec_to_bytes(0, ss);
+-	ba->maxlength = cw_pa.pa_usec_to_bytes(50*1000, ss);
++	ba->tlength = pa_usec_to_bytes(50*1000, ss);
++	ba->minreq = pa_usec_to_bytes(0, ss);
++	ba->maxlength = pa_usec_to_bytes(50*1000, ss);
+ 	/* ba->prebuf = ; */ /* ? */
+ 	/* ba->fragsize = sizeof(uint32_t) -1; */ /* not relevant to playback */
+ 
+-	pa_simple *s = cw_pa.pa_simple_new(NULL,                  /* server name (NULL for default) */
++	pa_simple *s = pa_simple_new(NULL,                  /* server name (NULL for default) */
+ 					   "libcw",               /* descriptive name of client (application name etc.) */
+ 					   PA_STREAM_PLAYBACK,    /* stream direction */
+ 					   dev,                   /* device/sink name (NULL for default) */
+@@ -258,47 +212,6 @@ pa_simple *cw_pa_simple_new_internal(pa_sample_spec *ss, pa_buffer_attr *ba, con
+ 
+ 
+ 
+-
+-
+-/**
+-   \brief Resolve/get symbols from PulseAudio library
+-
+-   Function resolves/gets addresses of few PulseAudio functions used by
+-   libcw and stores them in cw_pa global variable.
+-
+-   On failure the function returns negative value, different for every
+-   symbol that the funciton failed to resolve. Function stops and returns
+-   on first failure.
+-
+-   \param handle - handle to open PulseAudio library
+-
+-   \return 0 on success
+-   \return negative value on failure
+-*/
+-int cw_pa_dlsym_internal(void *handle)
+-{
+-	*(void **) &(cw_pa.pa_simple_new)         = dlsym(handle, "pa_simple_new");
+-	if (!cw_pa.pa_simple_new)         return -1;
+-	*(void **) &(cw_pa.pa_simple_free)        = dlsym(handle, "pa_simple_free");
+-	if (!cw_pa.pa_simple_free)        return -2;
+-	*(void **) &(cw_pa.pa_simple_write)       = dlsym(handle, "pa_simple_write");
+-	if (!cw_pa.pa_simple_write)       return -3;
+-	*(void **) &(cw_pa.pa_strerror)           = dlsym(handle, "pa_strerror");
+-	if (!cw_pa.pa_strerror)           return -4;
+-	*(void **) &(cw_pa.pa_simple_get_latency) = dlsym(handle, "pa_simple_get_latency");
+-	if (!cw_pa.pa_simple_get_latency) return -5;
+-	*(void **) &(cw_pa.pa_simple_drain)       = dlsym(handle, "pa_simple_drain");
+-	if (!cw_pa.pa_simple_drain)       return -6;
+-	*(void **) &(cw_pa.pa_usec_to_bytes)      = dlsym(handle, "pa_usec_to_bytes");
+-	if (!cw_pa.pa_usec_to_bytes)       return -7;
+-
+-	return 0;
+-}
+-
+-
+-
+-
+-
+ /**
+    \brief Open PulseAudio output, associate it with given generator
+ 
+@@ -325,16 +238,16 @@ int cw_pa_open_device_internal(cw_gen_t *gen)
+ 
+  	if (!gen->pa_data.s) {
+ 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "libcw_pa: can't connect to PulseAudio server: %s", cw_pa.pa_strerror(error));
++			      "libcw_pa: can't connect to PulseAudio server: %s", pa_strerror(error));
+ 		return false;
+ 	}
+ 
+ 	gen->buffer_n_samples = CW_PA_BUFFER_N_SAMPLES;
+ 	gen->sample_rate = gen->pa_data.ss.rate;
+ 
+-	if ((gen->pa_data.latency_usecs = cw_pa.pa_simple_get_latency(gen->pa_data.s, &error)) == (pa_usec_t) -1) {
++	if ((gen->pa_data.latency_usecs = pa_simple_get_latency(gen->pa_data.s, &error)) == (pa_usec_t) -1) {
+ 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-			      "libcw_pa: pa_simple_get_latency() failed: %s", cw_pa.pa_strerror(error));
++			      "libcw_pa: pa_simple_get_latency() failed: %s", pa_strerror(error));
+ 	}
+ 
+ #if CW_DEV_RAW_SINK
+@@ -357,20 +270,17 @@ void cw_pa_close_device_internal(cw_gen_t *gen)
+ 	if (gen->pa_data.s) {
+ 		/* Make sure that every single sample was played */
+ 		int error;
+-		if (cw_pa.pa_simple_drain(gen->pa_data.s, &error) < 0) {
++		if (pa_simple_drain(gen->pa_data.s, &error) < 0) {
+ 			cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
+-				      "libcw_pa: pa_simple_drain() failed: %s", cw_pa.pa_strerror(error));
++				      "libcw_pa: pa_simple_drain() failed: %s", pa_strerror(error));
+ 		}
+-		cw_pa.pa_simple_free(gen->pa_data.s);
++		pa_simple_free(gen->pa_data.s);
+ 		gen->pa_data.s = NULL;
+ 	} else {
+ 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_WARNING,
+ 			      "libcw_pa: called the function for NULL PA sink");
+ 	}
+ 
+-	if (cw_pa.handle) {
+-		dlclose(cw_pa.handle);
+-	}
+ 
+ #if CW_DEV_RAW_SINK
+ 	if (gen->dev_raw_sink != -1) {
+-- 
+2.16.2
+
diff --git a/nixpkgs/pkgs/applications/radio/urh/default.nix b/nixpkgs/pkgs/applications/radio/urh/default.nix
new file mode 100644
index 000000000000..730b679ba61e
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/urh/default.nix
@@ -0,0 +1,38 @@
+{ stdenv, lib, fetchFromGitHub, python3Packages
+, hackrf, rtl-sdr, airspy, limesuite, libiio
+, qt5
+, USRPSupport ? false, uhd }:
+
+python3Packages.buildPythonApplication rec {
+  pname = "urh";
+  version = "2.8.8";
+
+  src = fetchFromGitHub {
+    owner = "jopohl";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "0knymy85n9kxj364jpxjc4v9c238b00nl40rafi1ripkqx36bsfv";
+  };
+
+  nativeBuildInputs = [ qt5.wrapQtAppsHook ];
+  buildInputs = [ hackrf rtl-sdr airspy limesuite libiio ]
+    ++ lib.optional USRPSupport uhd;
+
+  propagatedBuildInputs = with python3Packages; [
+    pyqt5 numpy psutil cython pyzmq pyaudio setuptools
+  ];
+
+  postFixup = ''
+    wrapQtApp $out/bin/urh
+  '';
+
+  doCheck = false;
+
+  meta = with lib; {
+    homepage = "https://github.com/jopohl/urh";
+    description = "Universal Radio Hacker: investigate wireless protocols like a boss";
+    license = licenses.gpl3;
+    platforms = platforms.linux;
+    maintainers = with maintainers; [ fpletz ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/welle-io/default.nix b/nixpkgs/pkgs/applications/radio/welle-io/default.nix
new file mode 100644
index 000000000000..ce4c872821ec
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/welle-io/default.nix
@@ -0,0 +1,51 @@
+{ mkDerivation, lib, fetchFromGitHub, cmake, pkgconfig
+, qtbase, qtcharts, qtmultimedia, qtquickcontrols, qtquickcontrols2, qtgraphicaleffects
+, faad2, rtl-sdr, soapysdr-with-plugins, libusb-compat-0_1, fftwSinglePrec, lame, mpg123 }:
+let
+
+  version = "2.1";
+
+in mkDerivation {
+
+  pname = "welle-io";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "AlbrechtL";
+    repo = "welle.io";
+    rev = "v${version}";
+    sha256 = "1j63gdbd66d6rfjsxwdm2agrcww1rs4438kg7313h6zixpcc1icj";
+  };
+
+  nativeBuildInputs = [ cmake pkgconfig ];
+
+  buildInputs = [
+    faad2
+    fftwSinglePrec
+    lame
+    libusb-compat-0_1
+    mpg123
+    qtbase
+    qtcharts
+    qtmultimedia
+    qtquickcontrols
+    qtquickcontrols2
+    qtgraphicaleffects
+    rtl-sdr
+    soapysdr-with-plugins
+  ];
+
+  cmakeFlags = [
+    "-DRTLSDR=true" "-DSOAPYSDR=true"
+  ];
+
+  enableParallelBuilding = true;
+
+  meta = with lib; {
+    description = "A DAB/DAB+ Software Radio";
+    homepage = "https://www.welle.io/";
+    maintainers = with maintainers; [ ck3d markuskowa ];
+    license = licenses.gpl2;
+    platforms = with platforms; [ "x86_64-linux" "i686-linux" ] ++ darwin;
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/wsjtx/default.nix b/nixpkgs/pkgs/applications/radio/wsjtx/default.nix
new file mode 100644
index 000000000000..8e135dee5681
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/wsjtx/default.nix
@@ -0,0 +1,44 @@
+{ stdenv, fetchurl, asciidoc, asciidoctor, autoconf, automake, cmake,
+  docbook_xsl, fftw, fftwFloat, gfortran, libtool, libusb1, qtbase,
+  qtmultimedia, qtserialport, qttools, texinfo, wrapQtAppsHook }:
+
+stdenv.mkDerivation rec {
+  pname = "wsjtx";
+  version = "2.1.2";
+
+  # This is a "superbuild" tarball containing both wsjtx and a hamlib fork
+  src = fetchurl {
+    url = "http://physics.princeton.edu/pulsar/k1jt/wsjtx-${version}.tgz";
+    sha256 = "0aj3wg5xjjqwjvw6lra171ag5wq86w0hf1ra4k8mnaf0mc1qgbyl";
+  };
+
+  # Hamlib builds with autotools, wsjtx builds with cmake
+  # Omitting pkgconfig because it causes issues locating the built hamlib
+  nativeBuildInputs = [
+    asciidoc asciidoctor autoconf automake cmake docbook_xsl gfortran libtool
+    qttools texinfo wrapQtAppsHook
+  ];
+  buildInputs = [ fftw fftwFloat libusb1 qtbase qtmultimedia qtserialport ];
+
+  # Remove Git dependency from superbuild since sources are included
+  patches = [ ./super.patch ];
+
+  # Superbuild has its own patch step after it extracts the inner archives
+  postPatch = "cp ${./wsjtx.patch} wsjtx.patch";
+
+  meta = with stdenv.lib; {
+    description = "Weak-signal digital communication modes for amateur radio";
+    longDescription = ''
+      WSJT-X implements communication protocols or "modes" called FT4, FT8, JT4,
+      JT9, JT65, QRA64, ISCAT, MSK144, and WSPR, as well as one called Echo for
+      detecting and measuring your own radio signals reflected from the Moon.
+      These modes were all designed for making reliable, confirmed ham radio
+      contacts under extreme weak-signal conditions.
+    '';
+    homepage = "https://physics.princeton.edu/pulsar/k1jt/wsjtx.html";
+    # Older licenses are for the statically-linked hamlib
+    license = with licenses; [ gpl3Plus gpl2Plus lgpl21Plus ];
+    platforms = platforms.linux;
+    maintainers = with maintainers; [ lasandell ];
+  };
+}
diff --git a/nixpkgs/pkgs/applications/radio/wsjtx/super.patch b/nixpkgs/pkgs/applications/radio/wsjtx/super.patch
new file mode 100644
index 000000000000..d903171ffc5a
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/wsjtx/super.patch
@@ -0,0 +1,12 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 3bf97a4..2c9dce5 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -23,7 +23,6 @@ source tarball." )
+ #
+ # Find_library (USB_LIBRARY NAMES libusb.a usb)
+ Find_program (PATCH_EXECUTABLE patch REQUIRED)
+-Find_package (Git REQUIRED)
+ 
+ #
+ # extra C flags to minimize hamlib excutable sizes
diff --git a/nixpkgs/pkgs/applications/radio/wsjtx/wsjtx.patch b/nixpkgs/pkgs/applications/radio/wsjtx/wsjtx.patch
new file mode 100644
index 000000000000..fd7c40fdc13d
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/wsjtx/wsjtx.patch
@@ -0,0 +1,13 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 3e7e816b..e7dbb14a 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -885,6 +885,6 @@
+ #
+ 
+ # Widgets finds its own dependencies.
+-find_package (Qt5 COMPONENTS Widgets Multimedia PrintSupport Sql LinguistTools REQUIRED)
++find_package (Qt5 COMPONENTS Widgets Multimedia PrintSupport Sql LinguistTools SerialPort REQUIRED)
+ 
+ if (WIN32)
+   add_definitions (-DQT_NEEDS_QTMAIN)
diff --git a/nixpkgs/pkgs/applications/radio/xlog/default.nix b/nixpkgs/pkgs/applications/radio/xlog/default.nix
new file mode 100644
index 000000000000..e92c216466fc
--- /dev/null
+++ b/nixpkgs/pkgs/applications/radio/xlog/default.nix
@@ -0,0 +1,31 @@
+{ stdenv, fetchurl, glib, gtk2, pkgconfig, hamlib }:
+stdenv.mkDerivation rec {
+  pname = "xlog";
+  version = "2.0.19";
+
+  src = fetchurl {
+    url = "https://download.savannah.gnu.org/releases/xlog/${pname}-${version}.tar.gz";
+    sha256 = "0y38gkcm4mgv6wn31pjq6d5bm22m63rpwa55qjmrlywrmw76rppy";
+  };
+
+  # glib-2.62 deprecations
+  NIX_CFLAGS_COMPILE = "-DGLIB_DISABLE_DEPRECATION_WARNINGS";
+
+  buildInputs = [ glib pkgconfig gtk2 hamlib ];
+
+  meta = with stdenv.lib; {
+    description = "An amateur radio logging program";
+    longDescription =
+      '' Xlog is an amateur radio logging program.
+         It supports cabrillo, ADIF, trlog (format also used by tlf),
+         and EDI (ARRL VHF/UHF contest format) and can import twlog, editest and OH1AA logbook files.
+         Xlog is able to do DXCC lookups and will display country information, CQ and ITU zone,
+         location in latitude and longitude and distance and heading in kilometers or miles,
+         both for short and long path.
+      '';
+    homepage = "https://www.nongnu.org/xlog";
+    maintainers = [ maintainers.mafo ];
+    license = licenses.gpl3;
+    platforms = platforms.unix;
+  };
+}