• A modern implementation of the Parks-McClellan FIR design algorithm

    The Parks-McClellan FIR filter design algorithm is used to design optimal FIR filters according to a minimax criterion: it tries to find the FIR filter with a given number of coefficients whose frequency response minimizes the maximum weighted error with respect to a desired response over a finite set of closed sub-intervals of the frequency domain. It is based on the Remez exchange algorithm, which is an algorithm to find uniform approximations by polynomials using the equioscillation theorem. In signal processing, the Parks-McClellan algorithm is often call Remez. This algorithm is a very popular FIR design algorithm. Compared to the windowing method, which is another commonly used algorithm, it is able to obtain better filters (for instance, meeting design constraints with less coefficients), in part because it allows the designer to control the passband ripple and stopband attenuation independently by means of the weight function.

    I have been laying some groundwork for Maia SDR, and for this I will need to run the Parks-McClellan algorithm in maia-httpd, the piece of software that runs in the Pluto ARM CPU. To evaluate what implementation of this algorithm to use, I have first gone to the implementations that I normally use: the SciPy remez function, and GNU Radio’s pm_remez function. I read these implementations, but I didn’t like them much.

    The SciPy implementation is a direct C translation of the original Fortran implementation by McClellan, Parks and Rabiner from 1973. This C translation was probably written decades ago and never updated. The code is very hard to read. The GNU Radio implementation looks somewhat better. It is a C implementation that was extracted from Octave and dates from the 90s. The code is much easier to follow, but there are some comments saying “There appear to be some problems with the routine search. See comments therein [search for PAK:]. I haven’t looked closely at the rest of the code—it may also have some problems.” that have seemingly been left unattended.

    Because of this and since I want to keep all the Maia SDR software under permissive open source licenses (the GNU Radio / Octave implementation is GPL), I decided to write from scratch an implementation of the Parks-McClellan algorithm in Rust. The result of this has been the pm-remez crate, which I have released recently. It uses modern coding style and is inspired by recent papers about how to improve the numerical robustness of the Parks-McClellan algorithm. Since I figured that this implementation would also be useful outside of Maia SDR, I have written Python bindings and published a pm-remez Python package. This has a few neat features that SciPy’s remez function doesn’t have. The Python documentation gives a walkthrough of these by showing how to design several types of filters that are commonly used. This documentation is the best place to see what pm-remez is capable of.

    The rest of this post has some comments about the implementation and the things I’ve learned while working on this.

  • LTE Transmission Mode 4 (closed-loop spatial multiplexing)

    This is a long overdue post. In 2022, I wrote a series of posts about LTE as I studied its physical layer to understand it better. In the last post, I decoded the PDCCH (physical downlink control channel), which contains control information about each PDSCH (physical downlink shared channel) transmission. I found that, in the recording that I was using, some PDSCH transmissions used Transmission Mode 4 (TM4), which stands for closed-loop spatial multiplexing. For an eNB with two antenna ports (which is what I recorded), this transmission mode sends either one or two codewords simultaneously over the two ports by using a precoding matrix that is chosen from a list that contains a few options. The choice is done by means of channel-state information from the UE (hence the “closed-loop” in the name).

    In the post I found a transmission where only one codeword was transmitted. It used the precoding matrix \([1, i]^T/\sqrt{2}\). This basically means that a 90º phase offset is applied to the two antenna ports as they simultaneously transmit the same data. I mentioned that this was the reason why I obtained bad results when I tried to equalize this PDSCH transmission using transmit diversity in another previous post, and that in a future post I would show how to equalize this transmission correctly. I have realized that I never wrote this post, so now it is as good a time as any.

  • Decoding Queqiao-2

    Queqiao-2 is the second Chinese lunar relay satellite. It was launched on March 20 from Wenchang, and it carries a large 4.2 m deployable dish for communications on X-band with assets on the lunar surface (up to 10 simultaneous channels, according to Wikipedia). The satellite will be placed on a frozen elliptical orbit that gives a 20 hour communications window with assets near the lunar south pole on each 24 hour orbit. A very interesting experiment that it will perform is LOVEX, the Lunar Orbit VLBI Experiment. During the 4 hours per orbit that it spends around the periapsis over the lunar north pole, the 4.2 m antenna will be used for VLBI, both for radioastronomy and for orbit determination of deep space satellites, as part of the Chinese Deep Space Network.

    Queqiao-2 transmits telemetry on S-band, at 2234.5 MHz. In this post I will analyse a short IQ recording that Scott Tilley VE7TIL has shared with me.

  • 5G NR downlink reference signals

    Last summer I looked at the demodulation of the 5G NR downlink, using a short recording of an idle srsRAN gNB made by Benjamin Menkuec. In that post I looked at the phase compensation, which is new in NR compared to LTE, the SS/PBCH block, and performed OFDM demodulation of all the signals in the recording. One of these signals was the PDSCH transmitting the SIB1 (which is done periodically even on an idle cell), and its corresponding PDCCH transmission. However, there were some reference signals that I wasn’t able to identify at the time. In this post I will look at these reference signals in detail, and also to the DM-RS (demodulation reference signal) in the PDCCH and PDSCH.

  • Decoding IM-1

    IM-1, the first lunar lander mission from Intuitive Machines, also called Odysseus, was launched on February 15 from KSC, and landed on February 22 near Malapert crater, in the lunar south pole region. The mission has been a partial success. The vehicle did not manage to land upright, and broke one of its legs due to landing with too much horizontal velocity. Despite this unfavourable attitude, communications with the lander have been able to proceed at reduced data rates, and some images and science data have been returned. On February 29, the mission ended, as lunar night started on the landing location. Congratulations to Intuitive Machines for all the milestones achieved in their first mission.

    In this post I will examine some recordings of the S-band telemetry signal done by AMSAT-DL with the 20 metre antenna in Bochum observatory. These recordings were done while the lander was still in-orbit. When landed on the Moon, IM-1 used the same configuration, but the recordings done at Bochum are probably too weak to decode, due to the orientation of the lander antennas.


10ghz artemis1 astronomy astrophotography ATA ccsds ce5 contests digital modes doppler dslwp dsp eshail2 fec freedv frequency gmat gnss gnuradio gomx hermeslite hf jt kits lilacsat limesdr linrad lte microwaves mods moonbounce noise ofdm orbital dynamics outernet polarization radar radioastronomy radiosonde rust satellites sdr signal generators tianwen vhf & uhf