#!/usr/bin/env python # from kd7lmo web page # Demodulate an AM signal from the USRP or a recorded file. # The file format must be 256 ksps, complex data. # from gnuradio import gr, eng_notation, blks from gnuradio import audio from gnuradio import usrp from gnuradio.eng_option import eng_option from optparse import OptionParser import sys import math # # return a gr.flow_graph # def build_graph (file_name, freq_offset_khz): # Center IF frequency of down converter. IF_freq = 10.7e6 # Sampling rate of ADC on USRP adc_rate = 64e6 # Decimation rate from USRP ADC to IF. usrp_decim = 250 # Calculate the sampling rate of the USRP and capture file. if_rate = adc_rate / usrp_decim #256K # Decimate the IF sampling rate down by 4 to 64 ksps if_decim = 4 demod_rate = if_rate / if_decim #64K audio_decimation = 2 audio_rate = demod_rate / audio_decimation #32K # This is a flow graph that has an input (capture file) and output (audio channel). fg = gr.flow_graph () # Signal source is assumed to be 256 kspb / complex data stream. if (file_name == "usrp"): # Select USRP channel 0 mux = 0xf0f0f0f0 # Set the input mux to channel 0, real samples and decimation rate. src = usrp.source_c (0, usrp_decim, 1, mux) # Tune to the desired IF frequency. Our down converter inverts the RF spectrum, so we'll invert the frequency. src.set_rx_freq (0, -IF_freq) actual_IF_freq = src.rx_freq(0) src.set_pga (0, 20) else: src = gr.file_source (gr.sizeof_gr_complex, file_name) # Design the channel filter channel_coeffs = gr.firdes.low_pass (1.0, # gain if_rate, # input sample rate 8000,#cutoff freq of lpf 1000, #transition bandwidth gr.firdes.WIN_HANN) #window type print "len(channel_coeffs) = ", len(channel_coeffs) # Implement the channel filter ddc = gr.freq_xlating_fir_filter_ccf (if_decim, #decimation factor channel_coeffs, #filter coefficients freq_offset_khz, #frequency shift, in any if_rate) #input data rate # Demodule with classic sqrt (I*I + Q*Q) magblock = gr.complex_to_mag() # Scale the audio volumecontrol = gr.multiply_const_ff(.001) # Low pass filter the demodulator output audio_coeffs = gr.firdes.low_pass (1.0, demod_rate, 9e3, 4e3, gr.firdes.WIN_HANN) print "len(audio_coeffs) = ", len(audio_coeffs) # input: float; output: float audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs) # resampler to convert 64kbps to 48kbps for computer audio card rsamp=blks.rational_resampler_fff(fg,3,2) # sound card as final sink audio_sink = audio.sink (int (48000)) # now wire it all together fg.connect (src, ddc) fg.connect (ddc, magblock) fg.connect (magblock, volumecontrol) fg.connect (volumecontrol, audio_filter) fg.connect (audio_filter, rsamp) fg.connect (rsamp, (audio_sink, 0)) return fg def main (args): nargs = len (args) if nargs == 2: filename = args[0] freq_offset_khz = float (args[1]) * 1e3 else: sys.stderr.write ("usage: am_rcv_file {file_name,'usrp'} freq_offset_KHz\n") sys.exit (1) fg = build_graph (filename, freq_offset_khz) fg.start () raw_input ('Press Enter to quit: ') fg.stop () if __name__ == '__main__': main (sys.argv[1:])