In one of my previous project posts, I outlined how I had recently rediscovered my RTL-SDR dongle and wanted to start up a series on showing how to use it for learning/understanding waveform design for SDR (software defined radio) projects.
Since it had been a while since I last used my RTL-SDR dongle with GNU Radio, I found that the installation process had changed for my current version of Mac OS (as I outlined in my previous post as well).
Once I had GNU Radio installed with the OsmoSDR drivers for the RTL-SDR, I chose to create a flowgraph in GNU Radio that tuned to my local FM radio stations, demodulated the specified channel, and used my laptop's speakers as a sink to play the audio from. The idea being that this would prove that both my GNU Radio installation and RTL-SDR dongle were in sound working condition (please laugh at my pun).
I personally view the FM radio receiver flowgraph to be kind of like the "Hello World" or "blink LED" project of the RTL-SDR dongle with GNU Radio. It's a great starting point because it's a fairly low-complexity level flowgraph and has a very clear output that indicates successful function (being able to clearly hear the broadcast of the FM radio station from the PC speakers).
Since I covered the GNU Radio installation and the basics of RF antenna selection for an SDR application in that last post, I wanted to dedicate this write-up to going into the details of the DSP (digital signal processing) of the FM radio receiver flowgraph.
FM Radio Bare BonesIn the FM radio receiver flowgraph, the main four blocks that are the core of its functionality are the RTL-SDR Source block, a low pass filter, the WBFM Receive block, and Audio Sink.
This simple signal chain below will produce an audio output from your computer's speakers, however it won't sound as good as you'd be expecting from a normal radio since no additional signal conditioning is happening to achieve the best audio quality for output.
Starting with this bare-minimum signal processing chain is what I think helps convey that DSP in SDR is an iterative process during development, rather than a game of trying to build the perfect/most optimized system right out of the gate.
Starting with the RTL-SDR Source, this is the block in GNU Radio that is the interface to the RTL-SDR dongle, where its configuration settings are specified such as the center RF frequency, sample rate, gain, DC offset, etc.
It is built off the OSMOCOM drivers, which is why it appears under the OsmoSDR section in the Block Tree Panel.
The data that it outputs is complex baseband data that are the raw IQ samples coming from the RTL2832U chip that is the heart of the RTL-SDR. Currently, only Complex Float32 is the only supported output, but given this is the predominate complex data type used in the rest of the GNU Radio libraries, I don't see it being much of a constraint.
The Ch0 Frequency is the RF center frequency that the RTL-SDR dongle is tuned to receive on. So this is going to be the broadcast frequency of the target radio FM radio station to listen to.
The sample rate for the RTL-SDR dongle is the rate at which it will be capturing baseband RF data samples and outputting raw IQ data samples over the USB bus to the host PC. The RTL2832U has a theoretical maximum sample rate of 3.2Msps (3.2MHz).
Note: Msps = Mega samples per second
However, it has been historically noted by many users that the highest actual sample rate that can be used without dropping packets across the USB bus is 2.4Msps (2.4GHz). I personally like to always use a sample rate of 2.0Msps to make the downstream math easier with upsampling/downsampling.
In terms of Gain, 20dB for the RF, IF, and BB (baseband) gains are the ideal settings that I've found for picking up my local FM radio stations without distortion.
It may be tempting for beginners to crank up the gain settings in an attempt to get a stronger signal output from the RTL2832U, however if the target signal simply isn't strong enough (ie - the radio station is just out of range) then an increased gain setting will simply distort the signal. This is due in large part to the increased noise level that is mixed in the received signal is also being amplified by that same amount of gain.
If there is only one RTL-SDR dongle connected to a host PC, then the Ch: Antenna option can be left blank or set to 0. If multiple RTL-SDR dongles are connected, then they will index antenna values and one has to be specified.
Finally, the Ch: Bandwidth setting is to set the bandwidth of the bandpass filter on the radio frontend of the RTL-SDR dongle. The default value is 0, which configures the bandpass filter on the radio frontend of the RTL-SDR dongle to have a bandwidth equal to the sample rate.
So I set my sample rate to 2Msps (2MHz) so the bandpass filter on the RF frontend of my RTL-SDR dongle will have a bandwidth of 2MHz centered around the set RF center frequency of the radio station that I specify.
Once the RTL-SDR dongle has done it's job to receive and sample the target signal, the next step is to apply a low pass filter to that baseband data to filter out any unwanted signals around that target signal.
Because at this moment, anything within that 2MHz bandwidth from the RTL-SDR's frontend pass band filter centered around the RF center frequency is in the signal. This means you need to know what the bandwidth of your target signal is.
The target signal here is an FM radio station and FM radio stations are allocated 200kHz each, that puts the down-converted baseband signal coming from the RTL-SDR dongle centered around 0Hz spanning from -100kHz to +100kHz.
Since the spectrum is just a reflection around the center frequency, we only need to worry about the positive half of that spectrum from 0Hz to 100kHz. This is why most of the FM radio receiver GNU Radio flowgraph examples have the cutoff frequency of the low pass filter on the output of the RTL-SDR source set to 100kHz.
To get a little more granular, I found the frequency plot below that shows specifically what all data is transmitted within that 100kHz.
The monophonic audio channel occupies 0H - 15kHz, a pilot tone is located at 19kHz to be an indicator that stereo audio is also available at 23kHz - 53kHz, radio data system (RDS) information is broadcast at 57kHz to encode data like song/artist name, and finally subsidiary communications authorization (SCA) subcarriers are available at 67kHz and 92kHz. SCA subcarriers are for broadcasting additional services such as telemetry data of the transmitter.
These SCA subcarriers transmit data using narrow-band frequency modulation, which gives them a maximum frequency modulation range of 3kHz. Therefore if the 92kHz SCA subcarrier is in use, that gives us a maximum of 95kHz in the occupied bandwidth of 100kHz. So for my low pass filter, I set the cutoff frequency for the passband to 95kHz.
For the bandwidth of the transition band of a lowpass filter, while ideally it should be 0Hz (ie - any frequency above the cutoff is fully attenuated out) it actually needs to be wide enough so there is a smooth transition or "roll-off" from the passband to the stop band of the filter. Otherwise you get spikes in amplitude in your stop band that are large enough to hear in the audio later on.
The best width of your transition band depends on the design of the FIR filter that makes up the low pass filter. FIR filters have a drawback that their order (ie - number of required taps) increases exponentially as the desired transition band width decreases.
Since there is no way to control the number of taps in the underlying FIR filter that makes up the Low Pass Filter block in GNU Radio, you just have to set a transition width that works best with the number of taps it does have.
I've found that the transition band width to use with the Low Pass Filter block for the best filter performance is 10x's of what the passband width is set to. So since I set the cutoff frequency to 95kHz, I set the transition width to 950kHz.
Next, the block that's doing the grunt work of the flowgraph is the FM demodulator. The WBFM Receive block (WBFM = wide band frequency modulation) in GNU Radio performs an FM demodulation of the mono audio of the FM radio broadcast with deemphasis. If the full stereo demodulation is desired, the WBFM Receive PLL is used instead.
The quadrature rate of the WBFM Receive block is the data rate of the complex baseband signal being put into it. Which in the bare bones flow graph above would be equal to the sample rate of the RTL-SDR Source block (2Msps).
The audio decimation value is the factor that the quadrature rate is divided by to get the desired output audio data rate. Since audio speakers operate at a much lower rate than the rate at which the audio signal is sampled for processing in the flowgraph, it has to be decimated down to match.
Finally, in order to hear the audio from the flowgraph, the signal is fed into the Audio Sink block.
As I mentioned while the bare bones flowgraph above works, but it sure doesn't sound "right". The audio is wonky and distorted in all sorts of ways.
This ultimately goes back to the point I was touching on when describing the purpose of the audio decimation value in the WBFM Receive block where the baseband data that is the audio signal is being sampled out of the RTL-SDR at a much higher rate than speakers operate at.
DSP in SDRs is ultimately just a big game of matching/balancing signal data rates and sample rates to achieve the requirements of the system.
Your sample rates are going to be the highest when the carrier frequency is the highest in order to meet Nyquist requirements. So as you come down from the RF frequency, to the IF frequency, then into the baseband frequency and lower (ie - 48kHz audio output), you have to scale back you sample and data rates as you go through the system.
Increasing the rate of a signal is referred to as interpolation, while decreasing the rate is referred to as decimation. The data rate coming out of the RTL-SDR source is 2Msps (2MHz), which can be decimated immediately by a factor of four to 500ksps (500kHz) before going into the low pass filter.
A rational resampler block is used for interpolation/decimation, so I added one after the RTL-SDR Source block and before the Low Pass Filter with a decimation factor of 4 (interpolation is set to 1 which is no interpolation).
This means the quadrature rate of the WBFM receive block needs to be set to 500kHz. However, we now have a data stream at 500kHz that we ultimately need to be at 48kHz before going into the Audio Sink.
Since there isn't a nice way to directly divide 500kHz down to 48kHz, we have to play around with some resampling magic.
I set the decimation value in the WBFM Receive block was set to 10, so the audio stream coming out of it is 50kHz.
Adding another rational resampler block to the output of the WBFM Receive block, I decimated the signal down by another factor of 50 to get 1kHz. Then interpolated it by 48 to bring it back up to 48kHz.
Finally, a multiply constant is added to increase the amplitude of the signal before going into the Audio Sink block, which effectively increases the volume output from the PC speakers.
You can add a GUI control here for the value of the constant to change the volume of the audio output while the flowgraph is running.
Adding Visual ToolsSpeaking of GUI controls, I also like to add blocks such as the QT GUI Frequency Sink which provides a view of the target frequency spectrum. I chose to put it after the Low Pass Filter after the data rate has been decimated by a factor of 4 so the flowgraph doesn't consume as much memory resources on my host PC while running.
I'm also a fan of the waterfall graph to get a good view of the frequency domain over a given time interval.
It's a personal preference as to how many values you want to implement as variable blocks in the flowgraph. I do most of them, especially values that are used in multiple blocks so I only have to change them in the one variable block if I need to.
Finally, save and run the flowgraph to see what your target radio station sounds like.
Keep in mind that not all static and/or distortion is a matter of signal processing within your flowgraph. Outside factors such as the radio station being too far way and out of range cannot be completely fixed with DSP in the flowgraph. Neither can the wrong antenna for your application like I described in the antenna selection section of my previous post.
Essentially, if the signal is too messed up coming into your flowgraph, then there is only so much signal processing can do in the digital world.
Comments
Please log in or sign up to comment.