Month: January 2020

I had added bindings earlier for pulling data from the HackRF, and then more recently a binding to liquid-dsp frequency demodulation. But in between the two, filtering will be needed. So, I added a binding for the firdespm_lowpass function from liquid-dsp. This function gives you the coefficients for a Finite Impulse Response (FIR) filter, using the Parks-McClellan algorithm.

I wanted to see something interesting from that before going to bed, so I threw together a scheme procedure to generate and then print out the coefficients:

;; -*- geiser-scheme-implementation: guile -*-
;; Copyright 2020 Christopher Howard
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
(define-module (sdr filters)
#:export (print-firdespm-lowpass-coefficients))
(use-modules (rnrs bytevectors)
(sdr liquid-dsp))
(define (print-firdespm-lowpass-coefficients filter-len
cutoff-freq
stop-band-atten
fract-samp-offset)
(let ((output-bv (make-bytevector (* 4 filter-len))))
(firdespm-lowpass filter-len
cutoff-freq
stop-band-atten
fract-samp-offset
output-bv)
(let lp ((coeff 0))
(when (< coeff filter-len)
(display
(number->string
(bytevector-ieee-single-ref output-bv (* 4 coeff) (native-endianness))))
(display "\n")
(lp (1+ coeff))))))

I don’t really know enough yet to be sure if those are sane results or not, but it looks pretty. I was hoping to pick up a DSP book from the library sometime this week and dive more into the details of FIR filters.

No, I am not calling down an imprecation on radio technology. Rather, I want to highlight a great free software streaming radio system that uses a Curses-based interface:

Curseradio allows you to browse streaming radio stations listed in the opml.radiotime.com index. There is a large listing, and no proprietary software is required to view or to listen to the stations. Use arrow keys to select a station, “enter key” to start streaming, the “q” key to quit, and “k” to stop the streaming without quitting (i.e., pause).

In Guix, the command is “guix package -i curseradio” to install it. Note that a few days ago I had Guix fix a bug that was preventing the streaming from starting (a command path issue) so you may need to update your Guix channel, or cherry-pick Guix commit 8d8c6bf.

What is the (current) goal of the HackRF Shell project?

I aim to provide a free software program which sets up a Guile Scheme shell, allowing lisp-style control of the HackRF Software Defined Radio (SDR). The shell will provide procedures for (1) controlling the HackRF, including pulling from and pushing data to the radio, (2) Digital Signal Processing (DSP) e.g., frequency modulation, and (3) some i/o interfaces, specifically to the file system and to PulseAudio.

Why does this project exist?

Partly to help me learn about SDR and DSP. Also, I want to be able to code applications for HackRF SDR in Scheme, rather than in Python (Gnu Radio).

Wouldn’t it be better to use Guile FFI than embedding Guile in a C program?

Shouldn’t you make something modular to work with any SDR?

I wanted to focus on getting somewhere practical with the SDR I have and the code I already wrote. But I believe it would be possible to expand the shell by adding or swapping in osmocom bindings instead of just the libhackrf bindings.

What have you done so far?

Created the C program with libhackrf bindings

Set up autotools files for development

Created Guix package definitions for HackRF Shell as well as the hackrf and liquid-dsp libraries.

What are you working on now?

Adding liquid-dsp bindings.

Where is the code?

git clone git://git.librehacker.com/pub/git/hackrf-rkt.git

Why has it taken you so long to make progress on this project?

Toddlers

Moving to a new apartment.

A job with no PTO.

What makes Guix such an awesome development environment?

Once you’ve made package definitions, which isn’t very hard, you can set up your development environment (exposed packages and environment variables) quite easily. Right now, for HackRF I simple cd into my source code and run

guix environment hackrfshell --ad-hoc liquid-dsp

The I run ./configure, make, etc. In the next iteration of the hackrfshell package definition, I will add liquid-dsp as a dependency, so then it would just be guix environment hackrfshell.

Not all my package definitions have made it into the official Guix git repository yet, but I’ve added them to my local Guix channel for the same effect.

Also because of Guix’s functional package management approach, I can use any verions of libhackrf, etc. I want, and not have to worry about wrestling with base system dependencies.