I’ve been experimenting a bit with Software Defined Radio, and specifically the gqrx and gnuradio tools. One thing that took me longer than expected was figuring out how to work with the .raw files that gqrx can create when using the I/Q (In-Phase/Quadrature components) recorder – compared to .wav files (for which a plethora of tools exist), the .raw I/Q files record the entire spectrum visible in the waterfall window.
My basic requirement was extracting a few seconds worth of data from a longer recording to speed up my development cycle in gnuradio. I suspect many people use MATLAB or Octave for these kinds of things, but I thought there must be a simpler way.
I came across the following useful snippets while researching how to do this:
- According to this thread on discuss-gnuradio, the files contain “cf32, pairs of 32-bit floats representing I and Q.”
- Apparently, they are compatible with gnuradio’s file source/sink
- This gnuradio FAQ entry on reading file sink-produced files suggests using scipy.fromfile to read the data.
This is a good start, and I can now pull out the data I’m interested in using something like:
import matplotlib.pyplot as plt
import scipy
# gqrx_yyyymmdd_hhmmss_freq_samplerate_fc.raw
input_filename = "gqrx_20180410_201900_123430000_1800000_fc.raw"
output_suffix = "subset"
sample_rate = input_filename.split('_')[4]
with open(input_filename, 'rb') as f:
x = scipy.fromfile(f, dtype=scipy.complex64)
len(x)
# Look at the data
plt.plot(abs(x))
plt.show()
This produced a plot that looked something like this:

The signal of interest is clearly visible in the centre of the plot. This can now be extracted crudely using something like this:
# Determine region of interest & extract
start = int(2.8e7)
end = int(4.2e7)
roi = x[start:end]
Double-check your orders of magnitude 🙂
Figuring out the writing part took a bit of time and trial and error, but eventually I discovered that the following worked:
output_filename = input_filename.replace(".raw", output_suffix + ".raw")
with open(output_filename, 'wb') as f:
f.write(roi.tobytes())
It’s worth pointing out that gqrx determines the length of the file using the following code:
rec_len = (int)(info.size() / (sample_rate * bytes_per_sample));
, where sample_rate comes from the file name and bytes_per_sample is fixed at 8. This needs to give a sensible result.
Now I can use my smaller file in gnuradio and gqrx!

Please do leave a comment if this helped you, you know of a any other resources which discuss basic I/Q file editing, spot any mistakes or if you have anything else to add!
Hi! Thank you so much for your interesting trial!
It’s helpful to me~
By the way, already it may be an old story because your posting was updated two years ago,
I found a typo in your code example as follows:
with open(output_filename, ‘wb’) as 2:
f.write(roi.tobytes())
=> The number ‘2’ should be ‘f’… right?
Today(20.08.12.), still the code is shown as ‘as 2’…
Anyway, thank you again~!
Thank you for the feedback! I’m glad it was useful. I’ve now fixed the typo you identified.