GNU Radio / WiFi

I worked quite a lot on my GNU Radio WiFi transceiver and have some new stuff that I wanted to share.

The features introduced in this post are currently available in the development branch, as I plan further tests before merging them into master. If there are any problems with the development branch, I’m very happy to help.

Apart from testing, I’m still waiting for some fixes to the GNU Radio scheduler to get merged. Currently, GNU Radio does not allow to properly shut down some run to completion flow graphs that I use in simulations.

Sampling Offset Estimation

The frequency offset and sampling clock offset estimation was improved. The Sync Short and Sync Long blocks, which perform synchronization based on the short and long training sequence, now annotate the estimated frequency offsets. Later in the signal processing chain, this information is extracted and used to also estimate and correct sampling clock offsets.

The algorithms follow the paper “Frequency Offset Estimation and Correction in the IEEE 802.11a WLAN”, by Essam Sourour, Hussein El-Ghoroury and Dale McNeill.


One of my goals was to support more complex state-of-the-art channel estimation algorithms. Such algorithms are often decision-directed, i.e., they use the distance of data symbols to their ideal constellations point to adapt and improve the channel estimate over time.

Decision-directed equalizers have to know about the encoding of the current frame and the demapping decision. I, therefore, combined channel estimation, signal field decoding, and demapping of constellation points in one block.

Using WiFi constellation objects this was not as painful as it sounds. The new block, called Frame Equalizer provides also a very easy to use interface to plug in different channel estimation algorithms.

Channel Estimation

I used the new interface to implement some baseline and state-of-the-art algorithms. Currently, one can choose between LS, LMS, linear interpolation with the comb pilots, and Spectral Temporal Averaging (STA). The algorithms can even be changed during runtime.

Viterbi Deocder

Gonza Arcos made a pull request that included a faster Viterbi decoder. After some modifications, the code was merged. I did not yet do a comprehensive performance evaluation, but I’m very happy that the decoder and the constellation objects allowed me to, finally, get rid of IT++!

The drawback is, however, that the code used SSE2 instructions. In a perfect world, this would be encapsulated with VOLK. I’m not 100% sure, but I guess that basically every platform that is interesting for this module supports at least SSE2, so it might not be much of a problem.


Simulations were again improved and a sensitivity simulation was added. To promote simulations a bit, I moved the corresponding folder to the project root.

Using a Makefile it is really trivial to run simulations. A simple

make -j 5

starts 5 simulation runs in parallel, parses the data, and produces a plot like this: