What a view. . .

What a view. . .

Thursday, October 9, 2014

pyFmRadio - A Stereo FM Receiver For Your PC



My first software defined radio (SDR) project is a stereo FM receiver.  The project uses a rtl-sdr receiver and python under Linux.  It probably works on Win/Mac but I haven't verified that it does.  Design details are given below along with some nice supporting plots.  Skip to the bottom for the code.  Oh and this was my first time using python.  Have mercy.  ;)


Basics of FM Modulation

First things first.  Lets discuss how FM radio works.  Audio (voice, music, etc) is encoded onto a higher frequency signal (carrier) by varying the frequency of the carrier based on the amplitude of the audio signal.


Initial Signals
$Audio = A(t)$
$Carrier = \sin(2\pi f_ct )$

Frequency Modulated Signal
$Inst. Frequency = f_c + kA(t)$
$Phase = 2\pi\int\limits_0^tf_c + kA(t)\mathrm{d}t$
$Signal=\sin(2\pi f_ct + 2\pi k\int\limits_0^tA(t)\mathrm{d}t)$


A couple of things to remember in the above equations.
  • The audio signal is in units of amplitude.  Volts, quanta, etc.
  • The variable 'k' is a scaling term that controls the allowable frequency swing or bandwidth of the modulated signal.  It has units of $^{Hz}\!/\!_{Amp}$.
  • The frequency of the modulated signal is directly related to the amplitude of the audio signal.  If the amplitude is zero, the frequency of the modulated signal is equal to the carrier frequency.
  • Since $Frequency=\,^{\mathrm{d}phase}\!\!/\!_{\mathrm{d}t}$, the phase of the modulated signal is the integral of the frequency.  Since the carrier's frequency is unchanging, its integral is straight forward.  The integral of $A(t)$ generally cannot be simplified since it depends on a dynamic changing signal.  #RealWorldCalculus

Python code to create plot:
# Import the plotting library
from matplotlib import pyplot as plot

# Define the setup
fCarrier = 10;
fAudio = 1;
fs = 1000;
timeEnd = 1;
time = np.linspace(0,2,fs*timeEnd);

# Create the signals
carrier = np.sin(2*np.pi*fCarrier*time);
audio = np.sin(2*np.pi*fAudio*time);
audioInt = -np.cos(2*np.pi*fAudio*time);
freqMod = np.sin(2*np.pi*fCarrier*time + 2*np.pi*1*audioInt);

# Plot the signals
plot.plot(time,audio+3);
plot.plot(time,carrier);
plot.plot(time,freqMod-3);

# Add some description
plot.text(0.75,4.2,'Audio Signal');
plot.text(0.75,1.2,'Carrier Signal');
plot.text(0.75,-1.8,'FM Signal');

# Label and cleanup the axes
ax = plot.gca();
plot.xlabel('Time (sec)'); plot.ylim(-4.5,5); plot.title('Frequency Modulation Illustration');
ax.get_yaxis().set_ticks([]);



FM Broadcast Radio

Before diving into the design details of the FM receiver, I'll briefly discuss broadcast FM radio in the United States.  Some quick notes are immediately below and supporting illustrations follow. 
  • Each station is allowed to occupy 200KHz (Double-Side-Band) of bandwidth
  • Once demodulated, two audio signals are present, the Left+Right (mono) signal and the Left-Right (diff) signal
    • A handful of other signals are present but I am ignoring them for this project
  • The two audio signals allow for mono or stereo functionality
    • Stereo is formed by simple arithmetic: $Left =  mono+diff$, $Right=mono-diff$
  • The audio signals occupy 15KHz of bandwidth (Single-Side-Band)
  • The mono signal is at baseband while the diff signal is a Dual-Side-Band-Suppressed-Carrier (DSB-SC) 38KHz above
  • A pilot tone at 19KHz exists which can be used (after doubling) to baseband the difference signal.
FM Station Received via RTLSDR Receiver (still FM modulated)
Same FM Station As Above After Demodulation (and carrier frequency removed)
Cartoon Representation of Demodulated FM Signal (single-side-band)


Receiver Block Diagram

Having discussed FM and FM Broadcast Radio its time to jump right into the receiver design.  Below is a block diagram of pyFmRadio.

FM Demodulation and Audio Processing Block Diagram
Play-By-Play:
  • The RTLSDR receiver is set to a sample rate of 250Ksps.  It generates complex, 8bit IQ samples.
  • The receiver is centered on the carrier frequency of the signal.  This means the carrier frequency is no longer present in the FM signal equation:
$FM\,Signal=\sin(2\pi f_ct + 2\pi k\int\limits_0^tA(t)\mathrm{d}t)$ goes to $FM\,Signal=\sin(2\pi k\int\limits_0^tA(t)\mathrm{d}t)$ 
  • The "basebanded" FM signal is immediately demodulated.  The difference between consecutive samples is calculated via a delay discriminator and the arc-tangent function is used to calculate the angle of the differences.  This is approximately equal to differentiating the FM signal's phase or finding the instantaneous frequency.  You can see from the equation above that the instantaneous frequency of the basebanded signal is equal to the audio signal.
  • The Left+Right signal is singled out from the rest of the audio signals via filtering and its sampling rate is reduced to an audio sample rate.  This process is implemented as a polyphase decimation operation by making use of a nobel identity.  This implementation saves a considerable amount of processing time compared to a non-polyphase implementation where filtering is done first and then decimation if performed.
  • Using a high-q peaking filter, the 19KHz pilot tone is singled out from the demodulated signal.
  • The real-valued pilot signal is converted to an analytic signal via the Hilbert transform.
  • The frequency of the analytic pilot signal is easily doubled by computing the square of the signal.
  • The frequency-doubled pilot signal now serves as a frequency and phase coherent carrier (reconstructed carrier) that can be used to demodulate the Dual-Sideband-Suppressed-Carrier (DSB-SC) Left-Right signal.
  • The Left-Right signal is mixed down to baseband using the frequency-doubled pilot and it then undergoes the same polyphase decimation as the Left+Right signal did.
  • The two signals are scaled and DC filtered.
  • Next the two signals are passed through a de-emphasis filter.  The act of FM demodulation (specifically the derivative operation) amplifies high-frequency noise which degrades the SNR of higher frequency audio content.  To help with this, broadcasters apply a pre-emphasis filter that amplifies high frequencies relative to low frequencies.  On the receive side, the reciprocal operation (de-emphasis) is performed to flatten the signal's frequency response to its original state.  This process improves the Signal-to-Noise-Ratio (SNR) of the FM signal by reducing high-frequency noise.
  • Using addition and subtraction, the two signals (Left+Right and Left-Right) are converted into stereo signals (Left and Right).
  • That is it, now you have audio!
Viola! Audio!


Code




Copyright 2014 David Swiston