Listening to FM Radio in Software, Step by Step

Get started in software-defined radio with a project that can tune in two FM stations at once.
The Block Diagram

Figure 5 shows our strategy for listening to an FM station. If we remove the carrier, we're left with a baseband signal that has an instantaneous frequency proportional to the original message m(t). Thus, our challenge is to find a way to remove the carrier and compute the instantaneous frequency.

Figure 5. Block Diagram of FM Receiver

The first part is easy. We get rid of the carrier by using our software digital downconverter (DDC) block, freq_xlating_fir_filter_scf. This block is composed conceptually of a numerically controlled oscillator that generates sine and cosine waveforms at the frequency that we want to translate to zero, a mixer (that's a multiplier to us software folks) and a decimating finite impulse response filter. The scf suffix indicates that this block takes a stream of shorts on its input, produces a stream of complexes on its output and uses floating-point taps to specify the filter.

The digital downconverter does its job by taking advantage of a trigonometric identity that says when you multiply two sinusoids of frequency f1 and f2 together, the result is composed of two new sinusoids, one at f1+f2 and the other at f1–f2. In our case, we multiply the incoming signal by the frequency of the carrier. The output consists of two components, one at 2x the carrier and one at zero. We get rid of the 2x component with a low-pass filter, leaving us the baseband signal.

MIPS Are Us!

A straightforward implementation of the digital downconverter block in software is extremely expensive computationally. We'd be performing the sine and cosine generation and multiplication at the full input rate. On a Pentium 4, computing sine and cosine takes on the order of 150 cycles. Given a 20M sample/sec input stream, we'd be burning up 20e6 * 150 = 3e9 cycles/sec merely computing sine and cosine! Definitely a non-starter.

The good news is there's a better way to implement the DDC in software. This technique, described by Vanu Bose, et al., in “Virtual Radios” (see Resources), allows us to run all of the computation at the decimated rate by rearranging the order of the operations and using frequency-specific complex filter coefficients instead of real coefficients. The end result is a big win! We can do it in real time!

Quadrature Demodulation

The next job is to compute the instantaneous frequency of the baseband signal. We use the quadrature_demod_cf block for this. We approximate differentiating the phase by determining the angle between adjacent samples. Recall that the downconverter block produces complex numbers on its output. Using a bit more trigonometry, we can determine the angle between two subsequent samples by multiplying one by the complex conjugate of the other and then taking the arc tangent of the product. Listings 1 and 2 show the implementation of the quadrature_demod_cf block. Once you know what you want, it doesn't take much code. The bulk of the signal processing is the three-line loop in sync_work.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.


Anonymous's picture

and that is why lots of americans don't have jobs, right?

fm demodulation

dinesh's picture

sir, i need the total detail of fm demodulation which have sdr applications using vhdl domain and also matlab programs and vhdl coding for all about fm demodu.........
fm demodu rceiver circuit diagram also plz send it to my mailid as soon as possible sir


saamy's picture

I would like to start a New Fm station. can u give the details for what r the software we want to bye

Off-Line station break-out

JLM's picture

If the break-down of the signal(s) into multiple stations is too much for your CPU, how about recording a more raw version of the input and then breaking it down into multiple stations at a more leisurely rate, possibly even on more than one computer.

If this seems reasonable, could you give some ideas on where to make these changes?