What is GNU Radio?

A Complete FM Receiver

Example 2 shows a somewhat simplified but complete broadcast FM receiver. It includes control of the RF front end and all required signal processing. This example uses an RF front end built from a cable modem tuner and a 20M sample/sec analog-to-digital converter.

Example 2. Broadcast FM Receiver

#!/usr/bin/env python

from gnuradio import gr
from gnuradio import audio
from gnuradio import mc4020
import sys

def high_speed_adc (fg, input_rate):
    # return gr.file_source (gr.sizeof_short, "dummy.dat", False)
    return mc4020.source (input_rate, mc4020.MCC_CH3_EN | mc4020.MCC_ALL_1V)

#
# return a gr.flow_graph
#
def build_graph (freq1, freq2):
    input_rate = 20e6
    cfir_decimation = 125
    audio_decimation = 5

    quad_rate = input_rate / cfir_decimation
    audio_rate = quad_rate / audio_decimation

    fg = gr.flow_graph ()
   
    # use high speed ADC as input source
    src = high_speed_adc (fg, input_rate)
   
    # compute FIR filter taps for channel selection
    channel_coeffs = \
      gr.firdes.low_pass (1.0,          # gain
                          input_rate,   # sampling rate
                          250e3,        # low pass cutoff freq
                          8*100e3,      # width of trans. band
                          gr.firdes.WIN_HAMMING)

    # input: short; output: complex
    chan_filter1 = \
      gr.freq_xlating_fir_filter_scf (cfir_decimation,
                                      channel_coeffs,
                                      freq1,        # 1st station freq
                                      input_rate)
   
    (head1, tail1) = build_pipeline (fg, quad_rate, audio_decimation)
   
    # sound card as final sink
    audio_sink = audio.sink (int (audio_rate))

    # now wire it all together
    fg.connect (src, chan_filter1)
    fg.connect (chan_filter1, head1)
    fg.connect (tail1, (audio_sink, 0))

    return fg

def build_pipeline (fg, quad_rate, audio_decimation):
    '''Given a flow_graph, fg, construct a pipeline
    for demodulating a broadcast FM signal.  The
    input is the downconverted complex baseband
    signal. The output is the demodulated audio.

    build_pipeline returns a two element tuple
    containing the input and output endpoints.
    '''
    fm_demod_gain = 2200.0/32768.0
    audio_rate = quad_rate / audio_decimation
    volume = 1.0

    # input: complex; output: float
    fm_demod = gr.quadrature_demod_cf (volume*fm_demod_gain)

    # compute FIR filter taps for audio filter
    width_of_transition_band = audio_rate / 32
    audio_coeffs = gr.firdes.low_pass (1.0,            # gain
                                       quad_rate,      # sampling rate
                                       audio_rate/2 - width_of_transition_band,
                                       width_of_transition_band,
                                       gr.firdes.WIN_HAMMING)

    # input: float; output: float
    audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)

    fg.connect (fm_demod, audio_filter)
    return ((fm_demod, 0), (audio_filter, 0))
   

def main (args):
    nargs = len (args)
    if nargs == 1:
        # get station frequency from command line
        freq1 = float (args[0]) * 1e6
    else:
        sys.stderr.write ('usage: fm_demod freq\n')
        sys.exit (1)

    # connect to RF front end
    rf_front_end = gr.microtune_4937_eval_board ()
    if not rf_front_end.board_present_p ():
        raise IOError, 'RF front end not found'

    # set front end gain
    rf_front_end.set_AGC (300)

    # determine the front end's "Intermediate Frequency"
    IF_freq = rf_front_end.get_output_freq () # 5.75e6

    # Tell the front end to tune to freq1. 
    # I.e., freq1 is translated down to the IF frequency
    rf_front_end.set_RF_freq (freq1)

    # build the flow graph
    fg = build_graph (IF_freq, None)
   
    fg.start ()        # fork thread(s) and return
    raw_input ('Press Enter to quit: ')
    fg.stop ()

if __name__ == '__main__':
    main (sys.argv[1:])
Like the Hello World example, we build a graph, connect the blocks together and start it. In this case, our source, mc4020.source, is an interface to the Measurement Computing PCI-DAS 4020/12 high-speed ADC. We follow it with gr.freq_xlating_fir_filter_scf, a finite impulse response (FIR) filter that selects the FM station we're looking for and translates it to baseband (0Hz, DC). With the 20M sample/sec converter and cable modem tuner, we're really grabbing something in the neighborhood of a 6 MHz chunk of the spectrum. This single chunk may contain ten or more FM stations, and gr.freq_xlating_fir_filter_scf allows us to select the one we want.
In this case, we select the one at the exact center of the IF of the RF front end (5.75 MHz). The output of gr.freq_xlating_fir_filter_scf is a stream of complex samples at 160,000 samples/second. We feed the complex baseband signal into gr.quadrature_demod_cf, the block that does the actual FM demodulation.
gr.quadrature_demod_cf works by subtracting the angle of each adjacent complex sample, effectively differentiating the frequency. The output of gr.quadrature_demod_cf contains the left-plus-right FM mono audio signal, the stereo pilot tone at 19kHz, the left-minus-right stereo information centered at 38kHz and any other sub-carriers above that. For this simplified receiver, we finish off by low pass filtering and decimating the stream, keeping only the left-plus-right audio information, and send that to the sound card at 32,000 samples/sec.
For a more indepth look at how the FM receiver works, please see "Listening to FM, Step by Step."

Graphical User Interfaces

Graphical interfaces for GNU Radio applications are built in Python. Interfaces may be built using any toolkit you can access from Python; we recommend wxPython to maximize cross-platform portability. GNU Radio provides blocks that use interprocess communication to transfer chunks of data from the real-time C++ flow graph to Python-land.

What is GNU Radio?

 

ارتقاء امنیت وب با وف بومی