The Fast Fourier Transform (FFT) is used repeatedly in the digital signal processing (DSP) of software defined radios (SDRs). This ipython notebook is an attempt to make the FFT understandable for SDR users. It is specially written for my Electronics II students who are designing and building quadrature sampling detector (QSD) SDRs whose outputs feed the software part of the SDR in a computer through the sound card. Konrad McCLure's video on how the quadrature sampling detector works, is worth watching again, as it contains the background information you need, to understand the signals which enter the sound card. It will also help you understand the DSP which occurs inside the computer, because both processes involve throwing out an infinite amount of information to retain what we really care about, and the periodic snapshots analogy is also useful understanding how that works. A gnuradio flowgraph is also provided to demodulate single sideband (SSB) signals from a QSD SDR. Examining this flowgraph shows how the FFT is used over and over again in the DSP it does. As an example to make this description more concrete we will describe the process used to create the waterfall and spectral displays often seen in SDRs.

A radio signal is a well behaved function, and can be seen from two perspectives. The first one is what shows up on the oscilloscope, or a graph with the independent variable (horizontal axis) being time . The second way was discovered and/or popularized by Joseph Fourier, known mathematically as the Fourier series. It is basically the idea that given a time interval, we can express any "reasonable" function in that time interval as a linear combination (weighted sum) of harmonic sinusoids whose periods are coincident with that interval. Each sinusoid has a specific amplitude and is delayed a specific amount so that when you add them all up and graph the result in time, you have the first way of describing the radio signal. Both ways of describing the signals are useful. It should be stressed that the signal is the same; there are just these two useful ways of organizing the information the signal carries, or in other words, of describing the radio frequency signal we wish to listen to with our radio receiver. As an example, the python code below shows you how with just a few sinusoids, you can make a pretty good approximation of a square wave.

In [1]:

```
# Python script to calculate and plot the Fourier Series for sgn(cos(t))+1
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = [18, 5]
t = np.arange(-2*np.pi,2*np.pi, 0.02)
plt.plot(t, np.sign(np.cos(t))+1, t, np.ones(np.size(t)), t, 4/np.pi*np.cos(t), t, 4/5/np.pi*np.cos(5*t),
t, 4/7/np.pi*np.cos(7*t), t,
1 + 4/np.pi*np.cos(t) - 4/3/np.pi*np.cos(3*t) + 4/5/np.pi*np.cos(5*t) + 4/7/np.pi*np.cos(7*t))
plt.legend(['Square wave', 'DC term', 'Fundamental', 'Third harmonic','Fifth harmonic',
'Sum up to fifth harmonic'])
plt.xlabel('Time (s)')
plt.title('Fourier Series of a Square Wave')
plt.show()
```

Note how each sinusoid is periodic with the same period the square wave has.

The information we care about in our radio frequency signal is finite, because we can't hold an infinite amount of information in a computer or our brain. This means we need to select from the infinite amount of information the signal contains, only the parts we care about. What are these?

- First, we only care about the signal over a finite time interval (only while we are listening).
- Second, we want to listen to only one radio station during this time interval, which means only a limited band of frequencies are of interest.
- Third, we do not need infinite precision on any of our measurements.

We desire to keep only the information we care about, but still be able to organize it in time sequential fashion, or as a collection sinusoids. The graphs above give us hope. Our time interval of interest could be one period of the square wave, and realizing the plot above is made up of individual pixels on the screen, we only need a finite number of time measurements. Maybe we could just keep the first few or most important harmonic sinusoids as well, so both ways of looking at the data only require a finite amount of data. Time measurements could sampled every so often, using an analog to digital converter, or if we prefered to measure harmonics instead, we could construct a bank of bandpass filters, spaced out evenly over our band of frequencies, and measure the amplitude and phase outputs of each of them to represent the wave. We only need to pick one or the other of these measurement methods to collect the information about the signal we desire, because it should be possible to reorganize that information to view it from either perspective, and maybe the computer could do that work for us.

Because it is cheaper and more flexible, the periodic time sampling way is normally used, so we use it in our QSD SDR receivers. To make this process easier, the QSD circuit translates the band of frequencies of our radio station of interest down to audio frequencies whose sine waves are slowly varying. The "dot to dot" interpretation of our data allows us to get by with significantly fewer samples per second this way.

Two signals from the QSD enter the two channels (left audio capture and right audio capture) of the sound card. The sound card does the analog to digital conversion to change these signals into a set of signal measurements occurring every $T$ seconds, or uniformly timed data occurring $f_s = 1/T$ times a second. Essentially, what happens is an infinite amount of information is discarded so the remaining information will fit in the finite memory available in the computer. The assumption needed to do this is that a "dot to dot" interpretation of the resulting measurements is correct. This is basically the same as assuming the signals go smoothly between each data point, not going up and down between them, or more generally, they just don't change rapidly (have high frequency components to them). In the propeller example, it is like saying the propeller is going slowly, more precisely, it is not going around even half a cycle in the time between measurements, $T$.

As Konrad has shown, the radio frequency (RF) signal is sampled into two signals, called in-phase (I), and quadrature (Q). The QSD sampling and low pass filtering process shifts the RF signal down to the audio range, producing the intermediate frequency (IF) I and Q signals. The I signal is the same phase as the RF signal, and the Q signal is delayed by 90 degrees. Frequencies higher than audio are filtered out by the QSD, and the sound card also assists in this filtering process, so the I and Q signals only contain components with frequencies in the audio range. Their frequency spectrum (as seen on a spectrum analyzer) looks identical to the RF frequency spectrum centered on the local oscillator (LO) frequency of your SDR hardware, simply shifted down so the LO frequency in the RF signal looks identical to the DC signal in the I or Q signals. All the other frequencies not close to the LO frequencies are removed by the low pass filtering built into the QSD process. This process the QSD does for us eliminates an infinite amount of information and energy we don't care about (all the other radio stations we don't want to listen to), and it shifts the RF signal down to the audio spectrum where it is changing slowly.

In [2]:

```
import numpy as np
import matplotlib.pyplot as plt
N = 10
N_cont = 10*N
T = .5
f = .05
def signal_comparison(N, N_cont, T, f):
t_samp = np.arange(N)*T
t_cont = np.arange(N_cont)*T*(N/N_cont)
x1_cont = np.sin(2*np.pi*f*t_cont)
x2_cont = np.sin(2*np.pi*(f+1/T)*t_cont)
x1 = np.sin(2*np.pi*f*t_samp)
x2 = np.sin(2*np.pi*(f+1/T)*t_samp)
return t_cont, t_samp,x1_cont, x2_cont, x1, x2
t_cont, t_samp, x1_cont, x2_cont, x1, x2 = signal_comparison(N,
N_cont, T, f)
plt.plot(t_cont, x1_cont, t_cont, x2_cont, t_samp, x1, 'ro',
t_samp, x2, 'b*')
plt.grid()
plt.title('Two Signals With the Same Sample Points')
plt.show()
```

Now that we understand we need to sample fast enough, and the QSD makes that possible, we need to think about making a graph that shows how much of each frequency component we have in our signal. This is the spectrum diagram on top in the Quisk display below. The waterfall diagram is just the spectral diagram as it is repeatedly measured over time where color is used to signify signal strength instead of height. It is the lower diagram below in Quisk