HackRF Shell: Fun with filters

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))))))

Then I dumped some coefficients to a file:

(with-output-to-file "out.csv"
  (lambda () (print-firdespm-lowpass-coefficients 201 0.2 60.0 0)))

Plotting out the coefficients, I got this visual:

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.

Hackrf Racket Bindings: Update

I code bindings for the info functions, the functions used to pull basic information about the HackRF devices that are plugged in to USB.

racket@hackrf.rkt> (hackrf-init)
0
racket@hackrf.rkt> (define dl (get-hackrf-device-list))
racket@hackrf.rkt> (hackrf-device-count dl)
1
racket@hackrf.rkt> (hackrf-serial-numbers dl)
'("000000000000000087c867dc29903e5f")
racket@hackrf.rkt> 
racket@hackrf.rkt> (hackrf-usb-board-ids dl)
'(USB_BOARD_ID_HACKRF_ONE)
racket@hackrf.rkt> (hackrf-usb-device-index dl)
'(0)
racket@hackrf.rkt> (hackrf-usb-devices dl)
'(#<cpointer>)

There are a few earlier boards that are also supported by this interface besides just the HackRF One.

I’m coding for the version of libhackrf in Debian Stretch, which I’ve discovered is a few years older than the master branch. Maybe after finishing these binds I’ll create a new Git branch for the newer library, and update the bindings for it.

Here is the repo:

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

hackrf-rkt git repo

My project wasn’t big enough yet for Savannah, and I don’t like any of the other hosting options I’m familiar with, so I set up a git daemon for my libhackrf Racket bindings project:

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

This was something of an adventure, as (1) I found, and had to fix myself, a bug in Debian Stretch’s git-daemon-run package, and (2) the git-daemon config syntax was not quite intuitive to me, such that I had to tweak my parameters about five times while watching the system log, in order to export my repo.

Anyway, the clone should work from any IPv4 or IPv6 address, though I only tested IPv6. Let me know if there is a problem with IPv4 access.