Random Quote Board
Playing Back IQ Files with Gnu Radio
There are a lot of different SDRs, just as there are a lot of different SDR programs that you can use to control said SDRs. One thing that makes SDRs so useful is their ability to record IQ samples. If you're new to SDRs and digital signal processing and are wondering, "What's an IQ sample and why is it so important?", know this: the IQ samples are what comes off of the SDR. They're nothing more than numbers. But you can use those numbers to show you pretty spectra, demodulate signals to hear music or look at cool images, or track airplanes. By recording IQ samples, you're literally recording the samples coming off of the SDR. If you play them back, there's no difference between the samples when they first came off the SDR and when they're coming off of the hard drive or other storage media later. No difference at all..
I'm going to go through those programs that I've used to record IQ, then go through how I was able to play back the IQ samples using Gnu Radio.
"rtl_sdr" from Command Line
There's a small program for the RTL-type SDRs called, appropriately enough, "rtl_sdr". You can use this program from the command line to record IQ samples while controlling the center frequency, RF gain, sample rate and a few, other features. Here's an example showing a recording of a portion of the FM broadcast band with a 2.4 MHz sample rate, and also telling the system to collect 12 million samples (5 seconds).
rtl_sdr -f 90.9e6 -g 16 -s 2.4e6 -n 12e6 FM-Broadcast-90M9CF-2M4FS-20220611-1255.rsiq
Where:
- -f = set the center frequency. The "e6" means "x106", which means "MHz" in this context.
- -g = RF gain. The RTL-SDR has 29 gain settings (NOTE: If you ever want to see them, type "rtl_test" in the command line.) that are 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6. If you put in a simple integer value, the program will go with the next, lower value. For example, I put in a gain value of 16. The "rtl_sdr" program will use the next value lower than this, which is 15.7.
- -s = sample rate. Remember: You want the sample rate to be at least as high as any signal you wish to record. Which means, no, you cannot record ATSC or DVB-T signals with a RTL-SDR. Those signals are 6 MHz and 8 MHz wide, respectively. The RTL-SDR really putters out at 2.4 MHz. Sorry.
- -n = number of samples to collect. If you want to collect a signal for a certain number of seconds, multiply that time in seconds by the sample rate.
- file name: the last part will be the file name. I've used an extension of ".rsiq", which is my way of saying "IQ from an Rtl-Sdr".
Once I ran the program, it collected an IQ sample file. Do you know what such a file contains? Numbers. It contains numbers, which is all samples are. They're numbers. Nothing more. Using Gnu Octave, I was able to read the first ten numbers:
122 143 115 133 130 135 119 133 124 138
These ten numbers correspond to the first 5 values of both the in-phase (I) and quadrature (Q) signals. They alternate, with values 122, 115, 130, 119 and 124 being the in-phase (real) values and 143, 133, 135, 133 and 138 being the quadrature (imaginary) values. When I import a couple thousand values then divide them up in the same way, I can create a plot showing the two signals.
The RTL-SDR uses an 8-bit digitizer. Note that all of the numbers center around 128. The output from this program must be a straight, unsigned 8-bit number. This means that they have values between 0 - 255. To make these into standard Gnu Radio samples, we need to:
- Convert the 8-bit integers into floating point numbers.
- Subtract the value of 128 from the numbers so that it is truly centered on 0. If this is not removed, it shows up as a HUGE DC spike in the spectrum.
- Divide by 128 so that the signal is between +/- 1.
- Convert the samples into a complex stream that Gnu Radio can handle.
Gnu Radio only has one block that can be used to read unsigned 8-bit samples. This is the "UChar to Float" block. I then use an "Add" block to remove the value of 128 offset, followed by dividing by 128 so that all amplitudes fall between +/- 1. Then I split the samples to make them complex. Here's the flowgraph I used to read the samples directly.
SDR++
This program is a newer version of SDR# that is advertised as "the bloat-free SDR receiver". It's very similar to SDR#, though it has a version that will run on Linux. (NOTE: I've only been able to get SDR# to run on Windows.)
It has the ability to record IQ as well as demodulated audio. In both cases, it will create a .WAV file. Do you know what a .WAV file is? It's a file of samples (again, either IQ or audio) with a header in it. Specifically, a 44-byte header. I used Gnu Octave to read in an array of samples, all of them as 16-bit integers, then separated out the in-phase (real) and quadrature (imaginary) components.
SDR#
This is one of the more popular programs, though it only works on Windows (and perhaps Mac, though I've never worked with Macs, so I can't say.) SDR# has a lot of different plugins that extend its basic capabilities.
SDR# also provides the capabilities to record both IQ ("Baseband") and audio (demodulated) output. It can also set the bit encoding ("Sample Format", which is 8-bit integer, 16-bit integer and 32-bit floating point). Also, just as with SDR++, the output will be a .WAV file. The playback is the same as with SDR++. It doesn't matter the bit encoding for the .WAV file. The WAV File Source block will perform the correct conversion.
Spike
Signal Hound is a relatively small company in Washington state. They manufacture a small line of SDRs and computer-controlled signal generators. I saved up my pennies several years ago and purchased the BB60C, which I consider to be a high-end SDR.
The default for Spike is to act as a SDR controller to create a spectrum analyzer. It can also be run in "Zero Span" mode. This locks a spectrum analyzer to a single frequency. This is similar to all of the other SDRs and the software that controls them; the BB60C (or whatever SDR Spike is controlling) will be at a particular center frequency. The sample rate for the BB60C starts at 40 MHz and can be decimated by powers-of-2, up to a maximum decimation of 8192.
The "Zero Span" also provides the ability to both record and playback IQ files. Spike is different from the other programs in how it records IQ. Some programs ("rtl_sdr", GQRX, Gnu Radio "File Sink") record straight IQ samples with no metadata. Others (SDR#, SDR++) record with IQ samples together with metadata, called an "inline" recording. Spike records two, separate files. One is the IQ file; the other contains the metadata. This is called "detached" recording.
Spike provides for a lot of customization of IQ recording parameters. Aside from the reference level ("Ref Level", which also sets the input gain), it also allows you to set the sample rate, IF bandwidth, file record directory, file prefix, and the amount of time to be recorded. The IQ file will be a series of interleaved in-phase and quadrature 16-bit integers.
GQRX
GQRX is an open-source program based on Gnu Radio and QT. It was written by Alexandru Csete. Before I go into the details of IQ recording and playback, I will say this: GQRX is, without a doubt, the best demodulation of FM stations of ANY program I've ever listened to. Bar none. I've created frequency demodulators (as a matter of fact, I think I've made them all), and I cannot figure out how he does it. Since the program is based on Gnu Radio, I've attempted to replicate his flowgraph in Gnu Radio, and it still doesn't sound as nice. No idea what he did, exactly, but it's awesome!
As for the IQ recording and playback, I'm also going to give GQRX props for ease-of-use. By clicking on "Tools -> I/Q Recorder" (or pressing ctrl + I), GQRX pops up a window that can be used to set the recording directory where IQ files will be stored, start and stop recording by pressing the "Record" button, and playing back files by selecting an IQ recording file and pressing "Play".
GQRX stores IQ samples as complex 32-bit floating point samples. Such samples can be read into Gnu Radio directly using a "File Source" with output type set to "complex".
Gnu Radio
Yes, Gnu Radio itself can store IQ samples. Frankly, it's something at which it excels. You can store IQ samples as signed or unsigned 8-bit integers, signed 16-bit integers, or 32-bit floating point. You can store them as raw IQ samples (no metadata) or with metadata inline (using the "Wav File Sink"). NOTE: Gnu Radio also has the "File Meta Sink" which can also be used to store metadata as either an inline or detached file. I've not yet figured out how to use that block properly.)
Here's a short flowgraph that takes the IQ samples directly from a SDR and stores them in a file. In this case, the samples are stored as 32-bit floating point complex samples. While that may sound really complicated, remember two things:
- The samples are nothing more than numbers. Each number represents the measured voltage at periodic points from the original, analog waveform.
- The "complex" part means that each sample is represented by two numbers. They're stored in the file in sequential order as real-imaginary-real-imaginary... until the very end of the file.
The issue with storing the samples as 32-bit samples is that the file size will be quite large. Even a relatively small sample rate, such as 250 kSam/s, would still be a relatively large file. That sample rate for 30 seconds collecting 32-bit complex samples (8 bytes / sample) would still be a 60 MB file.
We can reduce the amount of storage required by switching to "byte" storage (8-bit samples), which will reduce the amount of required storage by 3/4 of what floating point requires. Thus, our 60 MB file would become a 15 MB file.
Conclusion
Gnu Radio can playback just about any IQ file recorded either in Gnu Radio itself, or in any other program. It's a matter of determining:
- What is the bit encoding of the samples? 8-bit? 16-bit? 32-bit? Integer or floating point?
- Is there any metadata in the file, called an "inline" file when the metadata and IQ samples are in the same file? If so, how do you account for that?
After that, its all up to you to figure out what you want to do with those samples.