Week 2 – Compiling…

After having prototyped the Signal Detector block last week, I implemented a first version in C++ this week. Also, I wrote a C++ prototype of the Signal Separator. To actually test it’s functionality, I need to implement the Signal Extractor block to be able to analyze one of the signals and compare it to the input (right now it’s just passing serialized samples of each signal).

Signal Detector

For this block, I used the volk method volk_32fc_s32f_x2_power_spectral_density_32f to estimate the PSD. I managed to output the estimated PSD as a float vector, so it can for now be plotted in a vector sink. Also, I have added a temporary second float vector output which is used to pass the detection borders for debugging purposes.

Since the block is now implemented as a decimating sync block, it consumes only as much items as needed by the chosen fft length.

I have abstained from normizing the PSD since this lead to incomparable plots if the input spectrum power is changing. Instead, the user can now set a detection threshold in dB or use the automatic threshold calculation with given sensitivity (between 0 and 1). Both seem to work fine.

The PSD can now be averaged with a single pole IIR filter (by given alpha in GRC).

Over-the-air detection of local radio stations


  • Instead of passing the start and stop frequency, I would rather pass the center frequency and bandwidth of each signal and quantize the bandwidth values. By doing this, the signal can be perfectly centered and the filters in the Signal Separator don’t need to be recalculated when small bandwidth changes occur.

Signal Separator

The signal separator now works with FIR filter kernels instead of Xlating FIR filter blocks. As a replacement, I implemented the Xlating functionality myself with rotator blocks.

Every time a message reaches the block, it recalculates the filters. In the work()-function, the input samples get filtered by the filter kernels and xlated with a rotator blocks. The decimated output samples are stored in vectors, which get passed in a message.

It is now possible to set an oversampling factor for the output samples to be able to filter more than just the detected signal edges.


  • Adapt filter calculation to new message format (see Signal Detector)
  • Write QA test

Signal Extractor

The third block I dealt with this week was the Signal Extractor. I wrote a first version in order to be able to write a test case for the separator (where I need the filtered samples of one signal for comparison). The block just extracts the samples of the specified signal number out of the message and passes them as gr_complex values.


For the next week, besides the mentioned tasks, I will start to implement the GUI block. If you want to try out what I have done so far, you can pull the master branch of the repo and check out the three examples. Cheers!