summaryrefslogtreecommitdiff
path: root/gnuradio-examples/python/usrp
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-examples/python/usrp')
-rw-r--r--gnuradio-examples/python/usrp/Makefile.am52
-rwxr-xr-xgnuradio-examples/python/usrp/am_rcv.py115
-rw-r--r--gnuradio-examples/python/usrp/ayfabtu.datbin0 -> 544640 bytes
-rwxr-xr-xgnuradio-examples/python/usrp/ayfabtu.py169
-rwxr-xr-xgnuradio-examples/python/usrp/benchmark_usb.py106
-rwxr-xr-xgnuradio-examples/python/usrp/dsb_tx.py51
-rwxr-xr-xgnuradio-examples/python/usrp/flexrf_debug.py169
-rwxr-xr-xgnuradio-examples/python/usrp/flexrf_siggen.py148
-rwxr-xr-xgnuradio-examples/python/usrp/fm_tx4.py171
-rwxr-xr-xgnuradio-examples/python/usrp/fm_tx_2_daughterboards.py160
-rwxr-xr-xgnuradio-examples/python/usrp/max_power.py83
-rwxr-xr-xgnuradio-examples/python/usrp/siggen_min2.py62
-rwxr-xr-xgnuradio-examples/python/usrp/test_counting.py53
-rwxr-xr-xgnuradio-examples/python/usrp/test_dft_analysis.py72
-rwxr-xr-xgnuradio-examples/python/usrp/test_dft_synth.py79
-rwxr-xr-xgnuradio-examples/python/usrp/test_digital_loopback_counting.py65
-rwxr-xr-xgnuradio-examples/python/usrp/test_digital_loopback_lfsr.py62
-rwxr-xr-xgnuradio-examples/python/usrp/tvrx_am_rcv_gui.py154
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_fft.py251
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_fft_old.py110
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_nbfm_ptt.py491
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_nbfm_rcv.py362
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_oscope.py252
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_rx_cfile.py107
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_rx_nogui.py186
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_siggen.py180
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_tv_rcv.py394
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py179
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_wfm_rcv.py269
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py144
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py153
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py311
-rwxr-xr-xgnuradio-examples/python/usrp/usrp_wxapt_rcv.py267
-rwxr-xr-xgnuradio-examples/python/usrp/wfm_rcv_file.py99
34 files changed, 5526 insertions, 0 deletions
diff --git a/gnuradio-examples/python/usrp/Makefile.am b/gnuradio-examples/python/usrp/Makefile.am
new file mode 100644
index 000000000..32442d5cb
--- /dev/null
+++ b/gnuradio-examples/python/usrp/Makefile.am
@@ -0,0 +1,52 @@
+#
+# Copyright 2004,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+EXTRA_DIST = \
+ am_rcv.py \
+ ayfabtu.py \
+ benchmark_usb.py \
+ fm_tx4.py \
+ fsk_loopback.py \
+ fsk_rx.py \
+ fsk_tx.py \
+ max_power.py \
+ test_counting.py \
+ test_dft_analysis.py \
+ test_dft_synth.py \
+ test_digital_loopback_counting.py \
+ test_digital_loopback_lfsr.py \
+ tvrx_am_rcv_gui.py \
+ tvrx_tv_rcv.py \
+ usrp_fft.py \
+ usrp_fft_old.py \
+ usrp_nbfm_ptt.py \
+ usrp_nbfm_rcv.py \
+ usrp_oscope.py \
+ usrp_rx_cfile.py \
+ usrp_rx_file.py \
+ usrp_rx_nogui.py \
+ usrp_siggen.py \
+ usrp_wfm_rcv.py \
+ usrp_wfm_rcv_nogui.py \
+ usrp_wfm_rcv2_nogui.py \
+ usrp_wfm_rcv_pll.py \
+ usrp_wxapt_rcv.py \
+ wfm_rcv_file.py
diff --git a/gnuradio-examples/python/usrp/am_rcv.py b/gnuradio-examples/python/usrp/am_rcv.py
new file mode 100755
index 000000000..2908dcbf5
--- /dev/null
+++ b/gnuradio-examples/python/usrp/am_rcv.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, eng_notation
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+
+from gnuradio.wxgui import stdgui, fftsink
+import wx
+
+class am_rx_graph (stdgui.gui_flow_graph):
+ def __init__(self,frame,panel,vbox,argv):
+ stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)
+
+ station = parseargs(argv[1:])
+ offset_freq = 30e3
+ IF_freq = offset_freq - station
+
+ adc_rate = 64e6
+ usrp_decim = 250
+ if_rate = adc_rate / usrp_decim # 256 kHz
+ if_decim = 4
+ demod_rate = if_rate / if_decim # 64 kHz
+ audio_decimation = 2
+ audio_rate = demod_rate / audio_decimation # 16 kHz
+
+ # usrp is data source
+ src = usrp.source_c (0, usrp_decim)
+ src.set_rx_freq (0, IF_freq)
+ actual_IF_freq =src.rx_freq(0)
+ actual_offset = actual_IF_freq + station
+
+ #print actual_IF_freq
+ #print actual_offset
+
+ src.set_pga(0,20)
+ # sound card as final sink
+ audio_sink = audio.sink (int (audio_rate))
+
+ channel_coeffs = \
+ gr.firdes.low_pass (1.0, # gain
+ if_rate, # sampling rate
+ 9e3, # low pass cutoff freq
+ 10e3, # width of trans. band
+ gr.firdes.WIN_HANN)
+
+ ddc = gr.freq_xlating_fir_filter_ccf (if_decim,channel_coeffs,-actual_offset,if_rate)
+
+ magblock = gr.complex_to_mag()
+ volumecontrol = gr.multiply_const_ff(.003)
+
+ # Deemphasis. Is this necessary on AM?
+ TAU = 75e-6 # 75us in US, 50us in EUR
+ fftaps = [ 1 - math.exp(-1/TAU/if_rate), 0]
+ fbtaps= [ 0 , math.exp(-1/TAU/if_rate) ]
+
+ deemph = gr.iir_filter_ffd(fftaps,fbtaps)
+
+ # compute FIR filter taps for audio filter
+ width_of_transition_band = audio_rate / 8
+ audio_coeffs = gr.firdes.low_pass (1.0, # gain
+ if_rate, # sampling rate
+ 9e3, #audio_rate/2 - width_of_transition_band,
+ 4e3, # width_of_transition_band,
+ gr.firdes.WIN_HANN)
+
+ # input: float; output: float
+ audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
+
+
+
+
+ print len(channel_coeffs)
+ print len(audio_coeffs)
+
+ # now wire it all together
+ self.connect (src, ddc)
+ self.connect (ddc, magblock)
+ self.connect (magblock, volumecontrol)
+ self.connect (volumecontrol,deemph)
+ self.connect (deemph,audio_filter)
+ self.connect (audio_filter, (audio_sink, 0))
+
+ if 1:
+ pre_demod = fftsink.fft_sink_c (self, panel, title="Pre-Demodulation", fft_size=128, sample_rate=if_rate)
+ self.connect (src, pre_demod)
+ vbox.Add (pre_demod.win, 1, wx.EXPAND)
+
+ if 0:
+ post_demod = fftsink.fft_sink_c (self, panel, title="Post Demodulation", fft_size=256, sample_rate=demod_rate)
+ self.connect (ddc, post_demod)
+ vbox.Add (post_demod.win, 1, wx.EXPAND)
+
+ if 0:
+ post_filt = fftsink.fft_sink_f (self, panel, title="Post Filter", fft_size=512, sample_rate=audio_rate)
+ self.connect (magblock,post_filt)
+ vbox.Add (post_filt.win, 1, wx.EXPAND)
+
+def parseargs (args):
+ nargs = len (args)
+ if nargs == 1:
+ freq1 = float (args[0]) * 1e3
+ else:
+ sys.stderr.write ('usage: am_rcv freq1\n')
+ sys.exit (1)
+
+ return freq1
+
+if __name__ == '__main__':
+ app = stdgui.stdapp (am_rx_graph, "AM RX")
+ app.MainLoop ()
+
diff --git a/gnuradio-examples/python/usrp/ayfabtu.dat b/gnuradio-examples/python/usrp/ayfabtu.dat
new file mode 100644
index 000000000..5c65cf483
--- /dev/null
+++ b/gnuradio-examples/python/usrp/ayfabtu.dat
Binary files differ
diff --git a/gnuradio-examples/python/usrp/ayfabtu.py b/gnuradio-examples/python/usrp/ayfabtu.py
new file mode 100755
index 000000000..7647e93b8
--- /dev/null
+++ b/gnuradio-examples/python/usrp/ayfabtu.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+#
+# Copyright 2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+#
+# All Your Frequencies are Belong to Us!
+#
+# Transmit NBFM message on 25 channels simultaneously!
+#
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio import usrp
+from gnuradio import audio
+from gnuradio import blks
+from gnuradio import optfir
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import math
+import sys
+import random
+
+from gnuradio.wxgui import stdgui, fftsink
+import wx
+
+
+def make_random_complex_tuple(L):
+ result = []
+ for x in range(L):
+ result.append(complex(random.gauss(0, 1),random.gauss(0, 1)))
+
+ return tuple(result)
+
+def random_noise_c():
+ src = gr.vector_source_c(make_random_complex_tuple(32*1024), True)
+ return src
+
+
+def plot_taps(taps, sample_rate=2):
+ return gru.gnuplot_freqz (gru.freqz (taps, 1), sample_rate)
+
+
+class ayfabtu_graph (stdgui.gui_flow_graph):
+ def __init__(self, frame, panel, vbox, argv):
+ stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+ parser = OptionParser (option_class=eng_option)
+ parser.add_option ("-c", "--duc-freq", type="eng_float", default=29.325e6,
+ help="set Tx ddc frequency to FREQ", metavar="FREQ")
+ (options, args) = parser.parse_args ()
+
+ nchan = 25
+ IF_GAIN = 80000
+ AUDIO_GAIN = 100
+
+ self.dac_rate = 128e6
+ self.usrp_interp = 256
+ self.usrp_rate = self.dac_rate / self.usrp_interp # 500 kS/s
+ self.audio_rate = 32000 # 32 kS/s
+
+ self.audio_src = gr.file_source(gr.sizeof_float, "ayfabtu.dat", True)
+
+ ahp_taps = gr.firdes.high_pass(1, # gain
+ 32e3, # Fs
+ 300, # cutoff
+ 600, # trans width
+ gr.firdes.WIN_HANN)
+ self.audio_hp = gr.fir_filter_fff(1, ahp_taps)
+
+ self.audio_gain = gr.multiply_const_ff(AUDIO_GAIN)
+
+ null_src = gr.null_source(gr.sizeof_gr_complex)
+ #noise_src = gr.noise_source_c(gr.GR_UNIFORM, 1, 0)
+ noise_src = random_noise_c()
+
+ if 0:
+ artaps = optfir.low_pass(1, # gain
+ 2, # Fs
+ .75/32, # freq1
+ 1.0/32, # freq2
+ 1, # pb ripple in dB
+ 50, # stopband atten in dB
+ 2) # + extra taps
+ else:
+ artaps = gr.firdes.low_pass(1, # gain
+ 32e3*15,# Fs
+ 2.7e3, # cutoff
+ .3e3, # trans width
+ gr.firdes.WIN_HANN)
+ print "len(artaps) =", len(artaps)
+ self.audio_resampler = blks.rational_resampler_fff(self, 15, 32, artaps)
+
+ self.fm_mod = blks.nbfm_tx(self, 15000, 15000, max_dev=4.5e3)
+
+
+ fbtaps = gr.firdes.low_pass(1, # gain
+ 25*15e3, # rate
+ 13e3, # cutoff
+ 2e3, # trans width
+ gr.firdes.WIN_HANN)
+ print "len(fbtabs) =", len(fbtaps)
+ #self.plot = plot_taps(fbtaps, 25*15e3)
+ self.filter_bank = blks.synthesis_filterbank(self, nchan, fbtaps)
+
+ self.if_gain = gr.multiply_const_cc(IF_GAIN)
+
+ if 0:
+ ifrtaps = optfir.low_pass(1,
+ 2, # Fs
+ .75/3, # freq1
+ 1.0/3, # freq2
+ 1, # pb ripple in dB
+ 50, # stopband atten in dB
+ 2) # + extra taps
+ else:
+ ifrtaps = gr.firdes.low_pass(1,
+ 2, # Fs
+ .75/3, # freq1
+ .25/3, # trans width
+ gr.firdes.WIN_HANN)
+
+
+ print "len(ifrtaps) =", len(ifrtaps)
+ self.if_resampler = blks.rational_resampler_ccf(self, 4, 3, ifrtaps)
+
+
+ self.u = usrp.sink_c(0, 256)
+ self.u.set_tx_freq(0, options.duc_freq)
+ self.u.set_pga(0, self.u.pga_max())
+
+ # wire it all together
+
+ self.connect(self.audio_src, self.audio_hp, self.audio_gain,
+ self.audio_resampler, self.fm_mod)
+
+ null_sink = gr.null_sink(gr.sizeof_gr_complex)
+
+ for i in range(nchan):
+ if True or i == 0:
+ self.connect(self.fm_mod, (self.filter_bank, i))
+ else:
+ self.connect(null_src, (self.filter_bank, i))
+
+ self.connect(self.filter_bank, self.if_gain, self.if_resampler, self.u)
+
+
+def main ():
+ app = stdgui.stdapp (ayfabtu_graph, "All Your Frequency Are Belong to Us")
+ app.MainLoop ()
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/benchmark_usb.py b/gnuradio-examples/python/usrp/benchmark_usb.py
new file mode 100755
index 000000000..8418f5062
--- /dev/null
+++ b/gnuradio-examples/python/usrp/benchmark_usb.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+"""
+Benchmark the USB/USRP throughput. Finds the maximum full-duplex speed
+the USRP/USB combination can sustain without errors.
+
+This program does not currently give reliable results. Sorry about that...
+"""
+
+from gnuradio import gr
+from gnuradio import usrp
+from gnuradio import eng_notation
+
+import sys
+
+def run_test (usb_throughput, verbose):
+ # usb_throughput is in bytes/sec.
+ #
+ # Returns True or False
+
+ nsec = 1
+ stream_length = int (usb_throughput/2 * nsec) # length of stream to examine
+
+ adc_freq = 64e6
+ dac_freq = 128e6
+ sizeof_sample = 2 * gr.sizeof_short
+
+ usb_throughput_in_samples = usb_throughput / sizeof_sample
+
+ # allocate usb throughput 50/50 between Tx and Rx
+
+ tx_interp = int (dac_freq) / int (usb_throughput_in_samples / 2)
+ rx_decim = int (adc_freq) / int (usb_throughput_in_samples / 2)
+
+ # print "tx_interp =", tx_interp, "rx_decim =", rx_decim
+ assert (tx_interp == 2 * rx_decim)
+
+ fg = gr.flow_graph ()
+
+ # Build the Tx pipeline
+ data_src = gr.lfsr_32k_source_s ()
+ src_head = gr.head (gr.sizeof_short, int (stream_length * 2))
+ usrp_tx = usrp.sink_s (0, tx_interp)
+ fg.connect (data_src, src_head, usrp_tx)
+
+ # and the Rx pipeline
+ usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK)
+ head = gr.head (gr.sizeof_short, stream_length)
+ check = gr.check_lfsr_32k_s ()
+ fg.connect (usrp_rx, head, check)
+
+ fg.run ()
+
+ ntotal = check.ntotal ()
+ nright = check.nright ()
+ runlength = check.runlength ()
+
+ if verbose:
+ print "usb_throughput =", eng_notation.num_to_str (usb_throughput)
+ print "ntotal =", ntotal
+ print "nright =", nright
+ print "runlength =", runlength
+ print "delta =", ntotal - runlength
+
+ return runlength >= stream_length - 80000
+
+def main ():
+ verbose = True
+ best_rate = 0
+ usb_rate = [ 2e6, 4e6, 8e6, 16e6, 32e6 ]
+ #usb_rate = [ 32e6, 32e6, 32e6, 32e6, 32e6 ]
+ # usb_rate.reverse ()
+ for rate in usb_rate:
+ sys.stdout.write ("Testing %sB/sec... " % (eng_notation.num_to_str (rate)))
+ sys.stdout.flush ()
+ ok = run_test (rate, verbose)
+ if ok:
+ best_rate = max (best_rate, rate)
+ sys.stdout.write ("OK\n")
+ else:
+ sys.stdout.write ("FAILED\n")
+
+ print "Max USB/USRP throughput = %sB/sec" % (eng_notation.num_to_str (best_rate),)
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/dsb_tx.py b/gnuradio-examples/python/usrp/dsb_tx.py
new file mode 100755
index 000000000..df65761cd
--- /dev/null
+++ b/gnuradio-examples/python/usrp/dsb_tx.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, eng_notation
+from gnuradio import usrp
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+
+def build_graph (cordic_freq):
+
+ audio_rate = 32000
+ sw_interp = 4
+ usrp_interp = 1000
+ audio_file = "/home/eb/demo/testing-audio.dat"
+
+ fg = gr.flow_graph ()
+
+ src = gr.file_source (gr.sizeof_float, audio_file, True)
+ gain = gr.multiply_const_ff (10000)
+
+ interp = gr.interp_fir_filter_fff (sw_interp, (1, 1, 1, 1))
+
+ f2c = gr.float_to_complex ()
+
+ u = usrp.sink_c (0, usrp_interp)
+ u.set_tx_freq (0, cordic_freq)
+
+ fg.connect (src, gain)
+ fg.connect (gain, interp)
+ fg.connect (interp, (f2c, 0))
+ fg.connect (interp, (f2c, 1))
+ fg.connect (f2c, u)
+
+ return fg
+
+def main ():
+ parser = OptionParser (option_class=eng_option)
+ parser.add_option ("-c", "--cordic-freq", type="eng_float", default=10e6,
+ help="set Tx cordic frequency to FREQ", metavar="FREQ")
+ (options, args) = parser.parse_args ()
+
+ print "cordic_freq = %s" % (eng_notation.num_to_str (options.cordic_freq))
+ fg = build_graph (options.cordic_freq)
+
+ fg.start ()
+ raw_input ('Press Enter to quit: ')
+ fg.stop ()
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/flexrf_debug.py b/gnuradio-examples/python/usrp/flexrf_debug.py
new file mode 100755
index 000000000..70c630960
--- /dev/null
+++ b/gnuradio-examples/python/usrp/flexrf_debug.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink, scopesink, slider
+from optparse import OptionParser
+import wx
+
+class app_flow_graph (stdgui.gui_flow_graph):
+ def __init__(self, frame, panel, vbox, argv):
+ stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+ self.frame = frame
+ self.panel = panel
+
+ parser = OptionParser (option_class=eng_option)
+ parser.add_option ("-d", "--decim", type="int", default=8,
+ help="set fgpa decimation rate to DECIM")
+ parser.add_option ("-c", "--ddc-freq", type="eng_float", default=0,
+ help="set Digital downconverter frequency to FREQ", metavar="FREQ")
+ parser.add_option ("-f", "--freq", type="eng_float", default=950e6,
+ help="set RF downconverter frequency to FREQ", metavar="FREQ")
+ parser.add_option ("-m", "--mux", type="intx", default=0x32103210,
+ help="set fpga FR_RX_MUX register to MUX")
+ parser.add_option ("-g", "--gain", type="eng_float", default=0,
+ help="set Rx PGA gain in dB (default 0 dB)")
+ (options, args) = parser.parse_args ()
+
+ self.u = usrp.source_c (0, options.decim, 1, gru.hexint(options.mux), 0)
+
+ self.u.set_verbose (0)
+
+ input_rate = self.u.adc_freq () / self.u.decim_rate ()
+
+ block = fftsink.fft_sink_c (self, panel, fft_size=1024, sample_rate=input_rate)
+ self.connect (self.u, block)
+ vbox.Add (block.win, 10, wx.EXPAND)
+
+ if 0:
+ c2f_1 = gr.complex_to_float ()
+ scope = scopesink.scope_sink_f (self, panel, "Rx Data", input_rate)
+ vbox.Add (scope.win, 6, wx.EXPAND)
+
+ self.connect (self.u,c2f_1)
+ self.connect ((c2f_1, 0), (scope, 0))
+ self.connect ((c2f_1, 1), (scope, 1))
+
+ if 0:
+ rms_complex = gr.rms_cf(.0001)
+ rms_i = gr.rms_ff(.0001)
+ rms_q = gr.rms_ff(.0001)
+
+ self.connect(self.u,rms_complex)
+ self.connect((c2f_1,0),rms_i)
+ self.connect((c2f_1,1),rms_q)
+
+ ns1 = gr.null_sink(4)
+ ns2 = gr.null_sink(4)
+ ns3 = gr.null_sink(4)
+
+ self.connect(rms_complex,ns1)
+ self.connect(rms_i,ns2)
+ self.connect(rms_q,ns3)
+
+ # sliders
+
+ #vbox.Add(slider.slider(panel, 0, 104, self.set_gain), 1, wx.ALIGN_CENTER)
+
+ #vbox.Add(slider.slider(panel, 0, 4095, self.set_gain_gc1), 1, wx.ALIGN_CENTER)
+ #vbox.Add(slider.slider(panel, 0, 31, self.set_gain_gc2), 1, wx.ALIGN_CENTER)
+ #vbox.Add(slider.slider(panel, 0, 1, self.set_gain_dl), 1, wx.ALIGN_CENTER)
+ #vbox.Add(slider.slider(panel, 0, 200, self.set_gain_i), 1, wx.ALIGN_CENTER)
+ #vbox.Add(slider.slider(panel, 0, 200, self.set_gain_q), 1, wx.ALIGN_CENTER)
+
+ self.offset = 0
+ #vbox.Add(slider.slider(panel, -200, 200, self.set_offset_i), 1, wx.ALIGN_CENTER)
+ #vbox.Add(slider.slider(panel, -200, 200, self.set_offset_q), 1, wx.ALIGN_CENTER)
+
+ vbox.Add(slider.slider(panel, 380, 480, self.set_rf_freq), 1, wx.EXPAND|wx.ALIGN_CENTER)
+ vbox.Add(slider.slider(panel, -32000, +32000, self.set_if_freq), 1, wx.EXPAND|wx.ALIGN_CENTER)
+ vbox.Add(slider.slider(panel, 0, 4095, self.set_gain), 1, wx.EXPAND|wx.ALIGN_CENTER)
+
+ # build small control area at bottom
+ hbox = wx.BoxSizer (wx.HORIZONTAL)
+ hbox.Add ((1, 1), 1, wx.EXPAND)
+ hbox.Add (wx.StaticText (panel, -1, "Set ddc freq: "), 0, wx.ALIGN_CENTER)
+ self.tc_freq = wx.TextCtrl (panel, -1, "", style=wx.TE_PROCESS_ENTER)
+ hbox.Add (self.tc_freq, 0, wx.ALIGN_CENTER)
+ wx.EVT_TEXT_ENTER (self.tc_freq, self.tc_freq.GetId(), self.handle_text_enter)
+ hbox.Add ((1, 1), 1, wx.EXPAND)
+ # add it to the main vbox
+ vbox.Add (hbox, 0, wx.EXPAND)
+
+ self.update_status_bar ()
+
+ def set_rf_freq (self,freq):
+ (success,actual_freq) = self.set_freq(1e6*freq)
+ if not success:
+ print "Failed on ",freq
+ def set_if_freq (self,freq):
+ self.u.set_rx_freq(0,freq*1e3)
+
+ def set_gain (self,gain):
+ self.rfrx.set_gain(gain)
+
+ def set_gain_i (self,gain):
+ self.u.set_pga(0,gain/10.0)
+ def set_gain_q (self,gain):
+ self.u.set_pga(1,gain/10.0)
+
+ def set_offset_i(self,offset):
+ self.offset = (self.offset & 0x0000ffff) | ((offset&0xffff)<<16)
+ self.u._write_fpga_reg (3,self.offset)
+
+ def set_offset_q(self,offset):
+ self.offset = (self.offset & 0xffff0000) | (offset&0xffff)
+ self.u._write_fpga_reg (3,self.offset)
+
+ def handle_text_enter (self, event):
+ str = event.GetString ()
+ self.tc_freq.Clear ()
+ self.u.set_rx_freq (0, eng_notation.str_to_num (str))
+ self.update_status_bar ()
+
+ def update_status_bar (self):
+ ddc_freq = self.u.rx_freq (0)
+ decim_rate = self.u.decim_rate ()
+ sample_rate = self.u.adc_freq () / decim_rate
+ msg = "decim: %d %sS/s DDC: %s" % (
+ decim_rate,
+ eng_notation.num_to_str (sample_rate),
+ eng_notation.num_to_str (ddc_freq))
+
+ self.frame.GetStatusBar().SetStatusText (msg, 1)
+
+ def set_gain(self,gain):
+ assert gain>=0 and gain<4096
+ self.u.write_aux_dac(0,0,int(gain))
+
+def main ():
+ app = stdgui.stdapp (app_flow_graph, "USRP FFT")
+ app.MainLoop ()
+
+if __name__ == '__main__':
+ main ()
+
+
diff --git a/gnuradio-examples/python/usrp/flexrf_siggen.py b/gnuradio-examples/python/usrp/flexrf_siggen.py
new file mode 100755
index 000000000..6a59148b8
--- /dev/null
+++ b/gnuradio-examples/python/usrp/flexrf_siggen.py
@@ -0,0 +1,148 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+from gnuradio.wxgui import stdgui, slider
+import wx
+
+class flex_siggen (stdgui.gui_flow_graph):
+ __slots__ = ['interp', 'waveform_type', 'waveform_ampl',
+ 'waveform_freq', 'waveform_offset', 'fg', 'usrp',
+ 'siggen', 'noisegen', 'src', 'file_sink' ]
+
+ def __init__ (self,frame,panel,vbox,argv):
+ stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+ self.frame = frame
+ self.panel = panel
+
+ parser = OptionParser (option_class=eng_option)
+ parser.add_option ("-a", "--amplitude", type="int", default=32000,
+ help="amplitude")
+ parser.add_option ("-i", "--interp", type="int", default=64,
+ help="set fpga interpolation rate to INTERP")
+ parser.add_option ("-n", "--nchannels", type="int", default=1,
+ help="set number of output channels to NCHANNELS")
+ (options, args) = parser.parse_args ()
+
+ self.waveform_type = gr.GR_CONST_WAVE
+ self.waveform_ampl = options.amplitude
+ self.waveform_freq = 100.12345e3
+ self.waveform_offset = 0
+
+ self.interp = options.interp
+ self._instantiate_blocks ()
+ self.usrp.set_nchannels (options.nchannels)
+
+ self.dboard=self.usrp.db[0][0]
+
+ self.set_waveform_type (self.waveform_type)
+ vbox.Add(slider.slider(panel, 390, 510, self.set_rf_freq), 1, wx.EXPAND|wx.ALIGN_CENTER)
+ vbox.Add(slider.slider(panel, -45000, +45000, self.set_if_freq), 1, wx.EXPAND|wx.ALIGN_CENTER)
+ #vbox.Add(slider.slider(panel, 0, 4095, self.set_gain), 1, wx.EXPAND|wx.ALIGN_CENTER)
+
+ def usb_freq (self):
+ return self.usrp.dac_freq() / self.interp
+
+ def usb_throughput (self):
+ return self.usb_freq () * 4
+
+ def set_waveform_type (self, type):
+ '''
+ valid waveform types are: gr.GR_SIN_WAVE, gr.GR_CONST_WAVE,
+ gr.GR_UNIFORM and gr.GR_GAUSSIAN
+ '''
+ self._configure_graph (type)
+ self.waveform_type = type
+
+ def set_waveform_ampl (self, ampl):
+ self.waveform_ampl = ampl
+ self.siggen.set_amplitude (ampl)
+ self.noisegen.set_amplitude (ampl)
+
+ def set_waveform_freq (self, freq):
+ self.waveform_freq = freq
+ self.siggen.set_frequency (freq)
+
+ def set_if_freq (self, freq):
+ self.if_freq = freq
+ self.usrp.set_tx_freq (0,freq*1e3)
+
+ def set_rf_freq (self, freq):
+ self.rf_freq = freq
+ (success,actual_freq) = self.dboard.set_freq (freq*1e6)
+ if not success:
+ print "Failed on ", freq
+
+ def set_waveform_offset (self, offset):
+ self.waveform_offset = offset
+ self.siggen.set_offset (offset)
+
+ def set_interpolator (self, interp):
+ self.interp = interp
+ self.siggen.set_sampling_freq (self.usb_freq ())
+ self.usrp.set_interp_rate (interp)
+
+ def set_duc_freq (self, freq):
+ self.usrp.set_tx_freq (0, freq)
+
+ def _instantiate_blocks (self):
+ self.src = None
+ self.usrp = usrp.sink_c (0, self.interp)
+
+ self.siggen = gr.sig_source_c (self.usb_freq (),
+ gr.GR_SIN_WAVE,
+ self.waveform_freq,
+ self.waveform_ampl,
+ self.waveform_offset)
+
+ self.noisegen = gr.noise_source_c (gr.GR_UNIFORM,
+ self.waveform_ampl)
+ print "done"
+
+ def _configure_graph (self, type):
+ was_running = self.is_running ()
+ if was_running:
+ self.stop ()
+ self.disconnect_all ()
+ if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE:
+ self.connect (self.siggen, self.usrp)
+ self.siggen.set_waveform (type)
+ self.src = self.siggen
+ elif type == gr.GR_UNIFORM or type == gr.GR_GAUSSIAN:
+ self.connect (self.noisegen, self.usrp)
+ self.noisegen.set_type (type)
+ self.src = self.noisegen
+ else:
+ raise ValueError, type
+ if was_running:
+ self.start ()
+
+
+if __name__ == '__main__':
+ parser = OptionParser (option_class=eng_option)
+ parser.add_option ("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE,
+ help="generate a complex sinusoid [default]", default=gr.GR_SIN_WAVE)
+ parser.add_option ("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE,
+ help="generate a constant output")
+ parser.add_option ("--gaussian", dest="type", action="store_const", const=gr.GR_GAUSSIAN,
+ help="generate Gaussian random output")
+ parser.add_option ("--uniform", dest="type", action="store_const", const=gr.GR_UNIFORM,
+ help="generate Uniform random output")
+ parser.add_option ("-f", "--freq", type="eng_float", default=100e3,
+ help="set waveform frequency to FREQ")
+ parser.add_option ("-r", "--rf-freq", type="eng_float", default=910e6,
+ help="set waveform frequency to FREQ")
+ parser.add_option ("-a", "--amplitude", type="eng_float", default=16e3,
+ help="set waveform amplitude to AMPLITUDE", metavar="AMPL")
+ parser.add_option ("-o", "--offset", type="eng_float", default=0,
+ help="set waveform offset to OFFSET")
+ parser.add_option ("-c", "--duc-freq", type="eng_float", default=0,
+ help="set Tx DUC frequency to FREQ", metavar="FREQ")
+ parser.add_option ("-m", "--mux", type="intx", default=0x98,
+ help="set output mux register")
+
+ app = stdgui.stdapp (flex_siggen, "USRP FlexRF Siggen")
+ app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/fm_tx4.py b/gnuradio-examples/python/usrp/fm_tx4.py
new file mode 100755
index 000000000..a9201b3f4
--- /dev/null
+++ b/gnuradio-examples/python/usrp/fm_tx4.py
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+
+"""
+Transmit N simultaneous narrow band FM signals.
+
+They will be centered at the frequency specified on the command line,
+and will spaced at 25kHz steps from there.
+
+The program opens N files with names audio-N.dat where N is in [0,7].
+These files should contain floating point audio samples in the range [-1,1]
+sampled at 32kS/sec. You can create files like this using
+audio_to_file.py
+"""
+
+from gnuradio import gr, eng_notation
+from gnuradio import usrp
+from gnuradio import audio
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import usrp_dbid
+import math
+import sys
+
+from gnuradio.wxgui import stdgui, fftsink
+from gnuradio import tx_debug_gui
+import wx
+
+
+########################################################
+# instantiate one transmit chain for each call
+
+class pipeline(gr.hier_block):
+ def __init__(self, fg, filename, lo_freq, audio_rate, if_rate):
+
+ src = gr.file_source (gr.sizeof_float, filename, True)
+ fmtx = blks.nbfm_tx (fg, audio_rate, if_rate,
+ max_dev=5e3, tau=75e-6)
+
+ # Local oscillator
+ lo = gr.sig_source_c (if_rate, # sample rate
+ gr.GR_SIN_WAVE, # waveform type
+ lo_freq, #frequency
+ 1.0, # amplitude
+ 0) # DC Offset
+ mixer = gr.multiply_cc ()
+
+ fg.connect (src, fmtx, (mixer, 0))
+ fg.connect (lo, (mixer, 1))
+
+ gr.hier_block.__init__(self, fg, src, mixer)
+
+
+
+class fm_tx_graph (stdgui.gui_flow_graph):
+ def __init__(self, frame, panel, vbox, argv):
+ MAX_CHANNELS = 7
+ stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+ parser = OptionParser (option_class=eng_option)
+ parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
+ help="select USRP Tx side A or B")
+ parser.add_option("-f", "--freq", type="eng_float", default=None,
+ help="set Tx frequency to FREQ [required]", metavar="FREQ")
+ parser.add_option("-n", "--nchannels", type="int", default=4,
+ help="number of Tx channels [1,4]")
+ parser.add_option("","--debug", action="store_true", default=False,
+ help="Launch Tx debugger")
+ (options, args) = parser.parse_args ()
+
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+
+ if options.nchannels < 1 or options.nchannels > MAX_CHANNELS:
+ sys.stderr.write ("fm_tx4: nchannels out of range. Must be in [1,%d]\n" % MAX_CHANNELS)
+ sys.exit(1)
+
+ if options.freq is None:
+ sys.stderr.write("fm_tx4: must specify frequency with -f FREQ\n")
+ parser.print_help()
+ sys.exit(1)
+
+ # ----------------------------------------------------------------
+ # Set up constants and parameters
+
+ self.u = usrp.sink_c () # the USRP sink (consumes samples)
+
+ self.dac_rate = self.u.dac_rate() # 128 MS/s
+ self.usrp_interp = 400
+ self.u.set_interp_rate(self.usrp_interp)
+ self.usrp_rate = self.dac_rate / self.usrp_interp # 320 kS/s
+ self.sw_interp = 10
+ self.audio_rate = self.usrp_rate / self.sw_interp # 32 kS/s
+
+ # determine the daughterboard subdevice we're using
+ if options.tx_subdev_spec is None:
+ options.tx_subdev_spec = usrp.pick_tx_subdevice(self.u)
+
+ m = usrp.determine_tx_mux_value(self.u, options.tx_subdev_spec)
+ #print "mux = %#04x" % (m,)
+ self.u.set_mux(m)
+ self.subdev = usrp.selected_subdev(self.u, options.tx_subdev_spec)
+ print "Using TX d'board %s" % (self.subdev.side_and_name(),)
+
+ self.subdev.set_gain(self.subdev.gain_range()[1]) # set max Tx gain
+ self.set_freq(options.freq)
+ self.subdev.set_enable(True) # enable transmitter
+
+ sum = gr.add_cc ()
+
+ # Instantiate N NBFM channels
+ step = 25e3
+ offset = (0 * step, 1 * step, -1 * step, 2 * step, -2 * step, 3 * step, -3 * step)
+ for i in range (options.nchannels):
+ t = pipeline (self, "audio-%d.dat" % (i % 4), offset[i],
+ self.audio_rate, self.usrp_rate)
+ self.connect (t, (sum, i))
+
+ gain = gr.multiply_const_cc (4000.0 / options.nchannels)
+
+ # connect it all
+ self.connect (sum, gain)
+ self.connect (gain, self.u)
+
+ # plot an FFT to verify we are sending what we want
+ if 1:
+ post_mod = fftsink.fft_sink_c(self, panel, title="Post Modulation",
+ fft_size=512, sample_rate=self.usrp_rate,
+ y_per_div=20, ref_level=40)
+ self.connect (sum, post_mod)
+ vbox.Add (post_mod.win, 1, wx.EXPAND)
+
+
+ if options.debug:
+ self.debugger = tx_debug_gui.tx_debug_gui(self.subdev)
+ self.debugger.Show(True)
+
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital up converter. Finally, we feed
+ any residual_freq to the s/w freq translater.
+ """
+
+ r = self.u.tune(self.subdev._which, self.subdev, target_freq)
+ if r:
+ print "r.baseband_freq =", eng_notation.num_to_str(r.baseband_freq)
+ print "r.dxc_freq =", eng_notation.num_to_str(r.dxc_freq)
+ print "r.residual_freq =", eng_notation.num_to_str(r.residual_freq)
+ print "r.inverted =", r.inverted
+
+ # Could use residual_freq in s/w freq translator
+ return True
+
+ return False
+
+def main ():
+ app = stdgui.stdapp (fm_tx_graph, "Multichannel FM Tx")
+ app.MainLoop ()
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py b/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py
new file mode 100755
index 000000000..1cb161018
--- /dev/null
+++ b/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+
+"""
+Transmit 2 signals, one out each daughterboard.
+
+Outputs SSB (USB) signals on side A and side B at frequencies
+specified on command line.
+
+Side A is 600 Hz tone.
+Side B is 350 + 440 Hz tones.
+"""
+
+from gnuradio import gr
+from gnuradio.eng_notation import num_to_str, str_to_num
+from gnuradio import usrp
+from gnuradio import audio
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import usrp_dbid
+import math
+import sys
+
+
+class example_signal_0(gr.hier_block):
+ """
+ Sinusoid at 600 Hz.
+ """
+ def __init__(self, fg, sample_rate):
+
+ src = gr.sig_source_c (sample_rate, # sample rate
+ gr.GR_SIN_WAVE, # waveform type
+ 600, # frequency
+ 1.0, # amplitude
+ 0) # DC Offset
+
+ gr.hier_block.__init__(self, fg, None, src)
+
+
+class example_signal_1(gr.hier_block):
+ """
+ North American dial tone (350 + 440 Hz).
+ """
+ def __init__(self, fg, sample_rate):
+
+ src0 = gr.sig_source_c (sample_rate, # sample rate
+ gr.GR_SIN_WAVE, # waveform type
+ 350, # frequency
+ 1.0, # amplitude
+ 0) # DC Offset
+
+ src1 = gr.sig_source_c (sample_rate, # sample rate
+ gr.GR_SIN_WAVE, # waveform type
+ 440, # frequency
+ 1.0, # amplitude
+ 0) # DC Offset
+ sum = gr.add_cc()
+ fg.connect(src0, (sum, 0))
+ fg.connect(src1, (sum, 1))
+
+ gr.hier_block.__init__(self, fg, None, sum)
+
+
+
+class my_graph(gr.flow_graph):
+
+ def __init__(self):
+ gr.flow_graph.__init__ (self)
+
+ usage="%prog: [options] side-A-tx-freq side-B-tx-freq"
+ parser = OptionParser (option_class=eng_option, usage=usage)
+ (options, args) = parser.parse_args ()
+
+ if len(args) != 2:
+ parser.print_help()
+ raise SystemExit
+ else:
+ freq0 = str_to_num(args[0])
+ freq1 = str_to_num(args[1])
+
+ # ----------------------------------------------------------------
+ # Set up USRP to transmit on both daughterboards
+
+ self.u = usrp.sink_c(nchan=2) # say we want two channels
+
+ self.dac_rate = self.u.dac_rate() # 128 MS/s
+ self.usrp_interp = 400
+ self.u.set_interp_rate(self.usrp_interp)
+ self.usrp_rate = self.dac_rate / self.usrp_interp # 320 kS/s
+
+ # we're using both daughterboard slots, thus subdev is a 2-tuple
+ self.subdev = (self.u.db[0][0], self.u.db[1][0])
+ print "Using TX d'board %s" % (self.subdev[0].side_and_name(),)
+ print "Using TX d'board %s" % (self.subdev[1].side_and_name(),)
+
+ # set up the Tx mux so that
+ # channel 0 goes to Slot A I&Q and channel 1 to Slot B I&Q
+ self.u.set_mux(0xba98)
+
+ self.subdev[0].set_gain(self.subdev[0].gain_range()[1]) # set max Tx gain
+ self.subdev[1].set_gain(self.subdev[1].gain_range()[1]) # set max Tx gain
+
+ self.set_freq(0, freq0)
+ self.set_freq(1, freq1)
+ self.subdev[0].set_enable(True) # enable transmitter
+ self.subdev[1].set_enable(True) # enable transmitter
+
+ # ----------------------------------------------------------------
+ # build two signal sources, interleave them, amplify and connect them to usrp
+
+ sig0 = example_signal_0(self, self.usrp_rate)
+ sig1 = example_signal_1(self, self.usrp_rate)
+
+ intl = gr.interleave(gr.sizeof_gr_complex)
+ self.connect(sig0, (intl, 0))
+ self.connect(sig1, (intl, 1))
+
+ # apply some gain
+ if_gain = 10000
+ ifamp = gr.multiply_const_cc(if_gain)
+
+ # and wire them up
+ self.connect(intl, ifamp, self.u)
+
+
+ def set_freq(self, side, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param side: 0 = side A, 1 = side B
+ @param target_freq: frequency in Hz
+ @rtype: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital up converter.
+ """
+
+ print "Tuning side %s to %sHz" % (("A", "B")[side], num_to_str(target_freq))
+ r = self.u.tune(self.subdev[side]._which, self.subdev[side], target_freq)
+ if r:
+ print " r.baseband_freq =", num_to_str(r.baseband_freq)
+ print " r.dxc_freq =", num_to_str(r.dxc_freq)
+ print " r.residual_freq =", num_to_str(r.residual_freq)
+ print " r.inverted =", r.inverted
+ print " OK"
+ return True
+
+ else:
+ print " Failed!"
+
+ return False
+
+
+if __name__ == '__main__':
+ try:
+ my_graph().run()
+ except KeyboardInterrupt:
+ pass
diff --git a/gnuradio-examples/python/usrp/max_power.py b/gnuradio-examples/python/usrp/max_power.py
new file mode 100755
index 000000000..b4ad86b09
--- /dev/null
+++ b/gnuradio-examples/python/usrp/max_power.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+"""
+Setup USRP for maximum power consumption.
+"""
+
+
+from gnuradio import gr
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+def ramp_source (fg):
+ period = 2**16
+ src = gr.vector_source_s (range (-period/2, period/2, 1), True)
+ return src
+
+def build_graph (tx_enable, rx_enable):
+ max_usb_rate = 8e6 # 8 MS/sec
+ dac_freq = 128e6
+ adc_freq = 64e6
+
+ tx_nchan = 2
+ tx_mux = 0x0000ba98
+ tx_interp = int (dac_freq / (max_usb_rate/2 * tx_nchan)) # 16
+
+ rx_nchan = 2
+ rx_mux = 0x00003210
+ rx_decim = int ((adc_freq * rx_nchan) / (max_usb_rate/2)) # 32
+
+ fg = gr.flow_graph ()
+
+ if tx_enable:
+ tx_src0 = gr.sig_source_c (dac_freq/tx_interp, gr.GR_CONST_WAVE, 0, 16e3, 0)
+ usrp_tx = usrp.sink_c (0, tx_interp, tx_nchan, tx_mux)
+ usrp_tx.set_tx_freq (0, 10e6)
+ usrp_tx.set_tx_freq (1, 9e6)
+ fg.connect (tx_src0, usrp_tx)
+
+ if rx_enable:
+ usrp_rx = usrp.source_c (0, rx_decim, rx_nchan, rx_mux)
+ usrp_rx.set_rx_freq (0, 5.5e6)
+ usrp_rx.set_rx_freq (1, 6.5e6)
+ rx_dst0 = gr.null_sink (gr.sizeof_gr_complex)
+ fg.connect (usrp_rx, rx_dst0)
+
+ return fg
+
+def main ():
+ parser = OptionParser (option_class=eng_option)
+ parser.add_option ("-t", action="store_true", dest="tx_enable",
+ default=False, help="enable Tx path")
+ parser.add_option ("-r", action="store_true", dest="rx_enable",
+ default=False, help="enable Rx path")
+ (options, args) = parser.parse_args ()
+ fg = build_graph (options.tx_enable, options.rx_enable)
+
+ fg.start ()
+ raw_input ('Press Enter to quit: ')
+ fg.stop ()
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/siggen_min2.py b/gnuradio-examples/python/usrp/siggen_min2.py
new file mode 100755
index 000000000..8709e3373
--- /dev/null
+++ b/gnuradio-examples/python/usrp/siggen_min2.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+
+
+def build_graph ():
+
+ # interp = 32
+ interp = 64
+ nchan = 2
+
+ if nchan == 1:
+ mux = 0x0098
+ #mux = 0x9800
+ else:
+ mux = 0xba98
+
+ f0 = 100e3
+ a0 = 16e3
+ duc0 = 5e6
+
+ f1 = 50e3
+ a1 = 16e3
+ duc1 = 7e6
+
+ fg = gr.flow_graph ()
+
+ u = usrp.sink_c (0, interp, nchan, mux)
+ sample_rate = u.dac_freq () / interp
+ print "sample_rate = ", eng_notation.num_to_str (sample_rate)
+ print "usb_sample_rate = ", eng_notation.num_to_str (sample_rate * nchan)
+
+ u.set_tx_freq (0, duc0)
+ u.set_tx_freq (1, duc1)
+
+ interleave = gr.interleave (gr.sizeof_gr_complex)
+ fg.connect (interleave, u)
+
+ src0 = gr.sig_source_c (sample_rate, gr.GR_SIN_WAVE, f0, a0, 0)
+ fg.connect (src0, (interleave, 0))
+
+ if nchan == 2:
+ if 1:
+ src1 = gr.sig_source_c (sample_rate, gr.GR_SIN_WAVE, f1, a1, 0)
+ else:
+ src1 = gr.noise_source_c (gr.GR_UNIFORM, a1)
+ fg.connect (src1, (interleave, 1))
+
+ return fg
+
+
+if __name__ == '__main__':
+ fg = build_graph ()
+ fg.start ()
+ raw_input ('Press Enter to quit: ')
+ fg.stop ()
+
diff --git a/gnuradio-examples/python/usrp/test_counting.py b/gnuradio-examples/python/usrp/test_counting.py
new file mode 100755
index 000000000..ed9328a33
--- /dev/null
+++ b/gnuradio-examples/python/usrp/test_counting.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+"""
+Check Rx path or USRP Rev 1.
+
+This configures the USRP to return a periodic sequence of integers
+"""
+
+from gnuradio import gr
+from gnuradio import usrp
+
+def build_graph ():
+ rx_decim = 32
+
+ fg = gr.flow_graph ()
+ usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_COUNTING)
+ sink = gr.check_counting_s ()
+ fg.connect (usrp_rx, sink)
+
+ # file_sink = gr.file_sink (gr.sizeof_short, 'counting.dat')
+ # fg.connect (usrp_rx, file_sink)
+
+ return fg
+
+def main ():
+ fg = build_graph ()
+ try:
+ fg.run()
+ except KeyboardInterrupt:
+ pass
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/test_dft_analysis.py b/gnuradio-examples/python/usrp/test_dft_analysis.py
new file mode 100755
index 000000000..a1d9eda46
--- /dev/null
+++ b/gnuradio-examples/python/usrp/test_dft_analysis.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, blks
+from gnuradio.wxgui import stdgui, fftsink, slider
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import wx
+
+class test_graph (stdgui.gui_flow_graph):
+ def __init__(self, frame, panel, vbox, argv):
+ stdgui.gui_flow_graph.__init__(self, frame, panel, vbox, argv)
+
+ parser = OptionParser (option_class=eng_option)
+ (options, args) = parser.parse_args ()
+
+ sample_rate = 16e3
+ mpoints = 4
+ ampl = 1000
+ freq = 0
+
+ lo_freq = 1e6
+ lo_ampl = 1
+
+ vbox.Add(slider.slider(panel,
+ -sample_rate/2, sample_rate/2,
+ self.set_lo_freq), 0, wx.ALIGN_CENTER)
+
+
+ src = gr.sig_source_c(sample_rate, gr.GR_CONST_WAVE,
+ freq, ampl, 0)
+
+ self.lo = gr.sig_source_c(sample_rate, gr.GR_SIN_WAVE,
+ lo_freq, lo_ampl, 0)
+
+ mixer = gr.multiply_cc()
+ self.connect(src, (mixer, 0))
+ self.connect(self.lo, (mixer, 1))
+
+ # We add these throttle blocks so that this demo doesn't
+ # suck down all the CPU available. Normally you wouldn't use these.
+ thr = gr.throttle(gr.sizeof_gr_complex, sample_rate)
+
+ taps = gr.firdes.low_pass(1, # gain
+ 1, # rate
+ 1.0/mpoints * 0.4, # cutoff
+ 1.0/mpoints * 0.1, # trans width
+ gr.firdes.WIN_HANN)
+ print len(taps)
+ analysis = blks.analysis_filterbank(self, mpoints, taps)
+
+ self.connect(mixer, thr)
+ self.connect(thr, analysis)
+
+ for i in range(mpoints):
+ fft = fftsink.fft_sink_c(self, frame, fft_size=128,
+ sample_rate=sample_rate/mpoints,
+ fft_rate=5,
+ title="Ch %d" % (i,))
+ self.connect((analysis, i), fft)
+ vbox.Add(fft.win, 1, wx.EXPAND)
+
+ def set_lo_freq(self, freq):
+ self.lo.set_frequency(freq)
+
+
+
+def main ():
+ app = stdgui.stdapp (test_graph, "Test DFT filterbank")
+ app.MainLoop ()
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/test_dft_synth.py b/gnuradio-examples/python/usrp/test_dft_synth.py
new file mode 100755
index 000000000..60a49e3b3
--- /dev/null
+++ b/gnuradio-examples/python/usrp/test_dft_synth.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, blks
+from gnuradio.wxgui import stdgui, fftsink
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import wx
+import random
+
+
+def make_random_complex_tuple(L, gain=1):
+ result = []
+ for x in range(L):
+ result.append(gain * complex(random.gauss(0, 1),random.gauss(0, 1)))
+
+ return tuple(result)
+
+def random_noise_c(gain=1):
+ src = gr.vector_source_c(make_random_complex_tuple(32*1024, gain), True)
+ return src
+
+
+class test_graph (stdgui.gui_flow_graph):
+ def __init__(self, frame, panel, vbox, argv):
+ stdgui.gui_flow_graph.__init__(self, frame, panel, vbox, argv)
+
+ parser = OptionParser (option_class=eng_option)
+ (options, args) = parser.parse_args ()
+
+ sample_rate = 16e6
+ mpoints = 16
+ ampl = 1000
+
+ enable = mpoints * [0]
+ enable[0] = 1
+
+ taps = gr.firdes.low_pass(1, # gain
+ 1, # rate
+ 1.0/mpoints * 0.4, # cutoff
+ 1.0/mpoints * 0.1, # trans width
+ gr.firdes.WIN_HANN)
+
+ synth = blks.synthesis_filterbank(self, mpoints, taps)
+
+ null_source = gr.null_source(gr.sizeof_gr_complex)
+
+ if 0:
+ for i in range(mpoints):
+ s = gr.sig_source_c(sample_rate/mpoints, gr.GR_SIN_WAVE,
+ 300e3, ampl * enable[i], 0)
+ self.connect(s, (synth, i))
+
+ else:
+ for i in range(mpoints):
+ if i == 0:
+ s = gr.sig_source_c(sample_rate/mpoints, gr.GR_SIN_WAVE,
+ 300e3, ampl * enable[i], 0)
+ #s = random_noise_c(ampl)
+ self.connect(s, (synth, i))
+ else:
+ self.connect(null_source, (synth, i))
+
+
+ # We add these throttle blocks so that this demo doesn't
+ # suck down all the CPU available. Normally you wouldn't use these.
+ thr = gr.throttle(gr.sizeof_gr_complex, sample_rate)
+ fft = fftsink.fft_sink_c(self, frame, fft_size=1024,
+ sample_rate=sample_rate)
+ vbox.Add(fft.win, 1, wx.EXPAND)
+
+ self.connect(synth, thr, fft)
+
+
+def main ():
+ app = stdgui.stdapp (test_graph, "Test DFT filterbank")
+ app.MainLoop ()
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/test_digital_loopback_counting.py b/gnuradio-examples/python/usrp/test_digital_loopback_counting.py
new file mode 100755
index 000000000..e985e4b4e
--- /dev/null
+++ b/gnuradio-examples/python/usrp/test_digital_loopback_counting.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+"""
+Digital loopback (Tx to Rx) for the USRP Rev1.
+"""
+
+
+from gnuradio import gr
+from gnuradio import usrp
+
+
+def ramp_source (fg):
+ period = 2**16
+ src = gr.vector_source_s (range (-period/2, period/2, 1), True)
+ return src
+
+def build_graph ():
+ tx_interp = 32 # tx should be twice rx
+ rx_decim = 16
+
+ fg = gr.flow_graph ()
+
+ data_src = ramp_source (fg)
+ # usrp_tx = usrp.sink_s (0, tx_interp, 1, 0x98)
+ usrp_tx = usrp.sink_s (0, tx_interp)
+ fg.connect (data_src, usrp_tx)
+
+ usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK)
+ sink = gr.check_counting_s ()
+ fg.connect (usrp_rx, sink)
+
+ # file_sink = gr.file_sink (gr.sizeof_short, "loopback.dat")
+ # fg.connect (usrp_rx, file_sink)
+
+ return fg
+
+def main ():
+ fg = build_graph ()
+ try:
+ fg.run()
+ except KeyboardInterrupt:
+ pass
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/test_digital_loopback_lfsr.py b/gnuradio-examples/python/usrp/test_digital_loopback_lfsr.py
new file mode 100755
index 000000000..ae78c7143
--- /dev/null
+++ b/gnuradio-examples/python/usrp/test_digital_loopback_lfsr.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+"""
+Digital loopback (Tx to Rx) for the USRP Rev1.
+"""
+
+from gnuradio import gr
+from gnuradio import usrp
+
+
+def build_graph ():
+ tx_interp = 32 # tx should be twice rx
+ rx_decim = 16
+
+ fg = gr.flow_graph ()
+
+ data_src = gr.lfsr_32k_source_s ()
+
+ # usrp_tx = usrp.sink_s (0, tx_interp, 1, 0x98)
+ usrp_tx = usrp.sink_s (0, tx_interp)
+
+ fg.connect (data_src, usrp_tx)
+
+ usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK)
+
+ sink = gr.check_lfsr_32k_s ()
+ fg.connect (usrp_rx, sink)
+
+ # file_sink = gr.file_sink (gr.sizeof_short, "loopback.dat")
+ # fg.connect (usrp_rx, file_sink)
+
+ return fg
+
+def main ():
+ fg = build_graph ()
+ try:
+ fg.run()
+ except KeyboardInterrupt:
+ pass
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/tvrx_am_rcv_gui.py b/gnuradio-examples/python/usrp/tvrx_am_rcv_gui.py
new file mode 100755
index 000000000..e4ad36931
--- /dev/null
+++ b/gnuradio-examples/python/usrp/tvrx_am_rcv_gui.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+#
+# Demodulate an AM signal from the TVRX or a recorded file.
+# The file format must be 256 ksps, complex data.
+#
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio import audio_oss as audio
+from gnuradio import usrp
+from gnuradio import tv_rx
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+from gnuradio.wxgui import stdgui, fftsink, scopesink
+import wx
+
+#
+# return a gr.flow_graph
+#
+class wfm_rx_graph (stdgui.gui_flow_graph):
+ def __init__(self,frame,panel,vbox,argv):
+ stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)
+
+ #set rf freq
+ rf_freq = 120.e6
+
+ # Decimation rate from USRP ADC to IF.
+ usrp_decim = 100
+
+ # Calculate the sampling rate of the USRP and capture file.
+ # Decimate the IF sampling rate down by 4 to 64 ksps
+ # This is a flow graph that has an input (capture file) and output (audio channel).
+ #self = gr.flow_graph ()
+
+ # Signal source is assumed to be 256 kspb / complex data stream.
+ which_side = 0
+ # usrp is data source
+ if which_side == 0:
+ src = usrp.source_c (0, usrp_decim, 1, gru.hexint(0xf0f0f0f0), 0)
+ else:
+ src = usrp.source_c (0, usrp_decim, 1, gru.hexint(0xf0f0f0f2), 0)
+
+ if_rate = 640e3 # src.adc_freq() / usrp_decim
+ if_decim = 5
+ demod_rate = if_rate / if_decim
+
+ audio_decimation = 4
+ audio_rate = demod_rate / audio_decimation
+
+ # set up frontend
+ dboard = tv_rx.tv_rx (src, which_side)
+ self.dboard = dboard
+ (success, actual_freq) = dboard.set_freq(rf_freq)
+ assert success
+
+ if_freq = rf_freq - actual_freq
+ src.set_rx_freq (0, -if_freq)
+
+ print "actual freq ", actual_freq
+ print "IF freq ", if_freq
+
+ dboard.set_gain(50)
+
+ #src = gr.file_source (gr.sizeof_gr_complex, "samples/atis_ffz_am_baseband_256k_complex.dat")
+ #src = gr.file_source (gr.sizeof_gr_complex, "samples/garagedoor1.dat", True)
+
+ #channel_coeffs = gr.firdes.band_pass (
+ # 1.0, # gain
+ # if_rate,
+ # 10, # center of low transition band
+ # 10000, # center of hi transition band
+ # 200, # width of transition band
+ # gr.firdes.WIN_HAMMING)
+
+ channel_coeffs = gr.firdes.low_pass (1.0, if_rate, 10e3, 4e3, gr.firdes.WIN_HANN)
+ print "len(channel_coeffs) = ", len(channel_coeffs)
+
+ # Tune to the desired frequency.
+ ddc = gr.freq_xlating_fir_filter_ccf (if_decim, channel_coeffs, -20e3, if_rate)
+
+ # Demodule with classic sqrt (I*I + Q*Q)
+ magblock = gr.complex_to_mag()
+
+ # Scale the audio
+ volumecontrol = gr.multiply_const_ff(.1)
+
+ #band-pass
+ audio_coeffs = gr.firdes.band_pass (
+ 1.0, # gain
+ demod_rate,
+ 10, # center of low transition band
+ 6000, # center of hi transition band
+ 200, # width of transition band
+ gr.firdes.WIN_HAMMING)
+
+
+ # Low pass filter the demodulator output
+ #audio_coeffs = gr.firdes.low_pass (1.0, demod_rate, 500, 200, 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)
+
+ # sound card as final sink
+ audio_sink = audio.sink (int (audio_rate))
+
+ # now wire it all together
+ self.connect (src, ddc)
+ self.connect (ddc, magblock)
+ self.connect (magblock, volumecontrol)
+ self.connect (volumecontrol, audio_filter)
+ self.connect (audio_filter, (audio_sink, 0))
+
+ d_win = fftsink.fft_sink_c (self, panel, title="RF", fft_size=512, sample_rate=if_rate)
+ self.connect (src,d_win)
+ vbox.Add (d_win.win, 4, wx.EXPAND)
+
+ p_win = fftsink.fft_sink_c (self, panel, title="IF", fft_size=512, sample_rate=demod_rate)
+ self.connect (ddc,p_win)
+ vbox.Add (p_win.win, 4, wx.EXPAND)
+
+ r_win = fftsink.fft_sink_f (self, panel, title="Audio", fft_size=512, sample_rate=audio_rate)
+ self.connect (audio_filter,r_win)
+ vbox.Add (r_win.win, 4, wx.EXPAND)
+
+ #audio_oscope = scopesink.scope_sink_f (self, panel, "Oscope Data", audio_rate)
+ #self.connect (audio_filter, audio_oscope)
+ #vbox.Add (audio_oscope.win, 4, wx.EXPAND)
+
+if __name__ == '__main__':
+
+ app = stdgui.stdapp (wfm_rx_graph, "TVRX AM RX")
+ app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/usrp_fft.py b/gnuradio-examples/python/usrp/usrp_fft.py
new file mode 100755
index 000000000..f760e39aa
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_fft.py
@@ -0,0 +1,251 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider
+from optparse import OptionParser
+import wx
+import sys
+
+
+def pick_subdevice(u):
+ """
+ The user didn't specify a subdevice on the command line.
+ If there's a daughterboard on A, select A.
+ If there's a daughterboard on B, select B.
+ Otherwise, select A.
+ """
+ if u.db[0][0].dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
+ return (0, 0)
+ if u.db[1][0].dbid() >= 0:
+ return (1, 0)
+ return (0, 0)
+
+
+class app_flow_graph(stdgui.gui_flow_graph):
+ def __init__(self, frame, panel, vbox, argv):
+ stdgui.gui_flow_graph.__init__(self)
+
+ self.frame = frame
+ self.panel = panel
+
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+ help="select USRP Rx side A or B (default=first one with a daughterboard)")
+ parser.add_option("-d", "--decim", type="int", default=16,
+ help="set fgpa decimation rate to DECIM [default=%default]")
+ parser.add_option("-f", "--freq", type="eng_float", default=None,
+ help="set frequency to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=None,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option("-W", "--waterfall", action="store_true", default=False,
+ help="Enable waterfall display")
+ parser.add_option("-8", "--width-8", action="store_true", default=False,
+ help="Enable 8-bit samples across USB")
+ parser.add_option("-S", "--oscilloscope", action="store_true", default=False,
+ help="Enable oscilloscope display")
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+
+ self.show_debug_info = True
+
+ # build the graph
+
+ self.u = usrp.source_c(decim_rate=options.decim)
+ if options.rx_subdev_spec is None:
+ options.rx_subdev_spec = pick_subdevice(self.u)
+ self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+
+ if options.width_8:
+ width = 8
+ shift = 8
+ format = self.u.make_format(width, shift)
+ print "format =", hex(format)
+ r = self.u.set_format(format)
+ print "set_format =", r
+
+ # determine the daughterboard subdevice we're using
+ self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+
+ input_rate = self.u.adc_freq() / self.u.decim_rate()
+
+ if options.waterfall:
+ self.scope = \
+ waterfallsink.waterfall_sink_c (self, panel, fft_size=1024, sample_rate=input_rate)
+ elif options.oscilloscope:
+ self.scope = scopesink.scope_sink_c(self, panel, sample_rate=input_rate)
+ else:
+ self.scope = fftsink.fft_sink_c (self, panel, fft_size=1024, sample_rate=input_rate)
+
+ self.connect(self.u, self.scope)
+
+ self._build_gui(vbox)
+
+ # set initial values
+
+ if options.gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.subdev.gain_range()
+ options.gain = float(g[0]+g[1])/2
+
+ if options.freq is None:
+ # if no freq was specified, use the mid-point
+ r = self.subdev.freq_range()
+ options.freq = float(r[0]+r[1])/2
+
+ self.set_gain(options.gain)
+
+ if self.show_debug_info:
+ self.myform['decim'].set_value(self.u.decim_rate())
+ self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
+ self.myform['dbname'].set_value(self.subdev.name())
+ self.myform['baseband'].set_value(0)
+ self.myform['ddc'].set_value(0)
+
+ if not(self.set_freq(options.freq)):
+ self._set_status_msg("Failed to set initial frequency")
+
+ def _set_status_msg(self, msg):
+ self.frame.GetStatusBar().SetStatusText(msg, 0)
+
+ def _build_gui(self, vbox):
+
+ def _form_set_freq(kv):
+ return self.set_freq(kv['freq'])
+
+ vbox.Add(self.scope.win, 10, wx.EXPAND)
+
+ # add control area at the bottom
+ self.myform = myform = form.form()
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0, 0)
+ myform['freq'] = form.float_field(
+ parent=self.panel, sizer=hbox, label="Center freq", weight=1,
+ callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+ hbox.Add((5,0), 0, 0)
+ g = self.subdev.gain_range()
+ myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain",
+ weight=3,
+ min=int(g[0]), max=int(g[1]),
+ callback=self.set_gain)
+
+ hbox.Add((5,0), 0, 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ self._build_subpanel(vbox)
+
+ def _build_subpanel(self, vbox_arg):
+ # build a secondary information panel (sometimes hidden)
+
+ # FIXME figure out how to have this be a subpanel that is always
+ # created, but has its visibility controlled by foo.Show(True/False)
+
+ def _form_set_decim(kv):
+ return self.set_decim(kv['decim'])
+
+ if not(self.show_debug_info):
+ return
+
+ panel = self.panel
+ vbox = vbox_arg
+ myform = self.myform
+
+ #panel = wx.Panel(self.panel, -1)
+ #vbox = wx.BoxSizer(wx.VERTICAL)
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+
+ myform['decim'] = form.int_field(
+ parent=panel, sizer=hbox, label="Decim",
+ callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg))
+
+ hbox.Add((5,0), 1)
+ myform['fs@usb'] = form.static_float_field(
+ parent=panel, sizer=hbox, label="Fs@USB")
+
+ hbox.Add((5,0), 1)
+ myform['dbname'] = form.static_text_field(
+ parent=panel, sizer=hbox)
+
+ hbox.Add((5,0), 1)
+ myform['baseband'] = form.static_float_field(
+ parent=panel, sizer=hbox, label="Analog BB")
+
+ hbox.Add((5,0), 1)
+ myform['ddc'] = form.static_float_field(
+ parent=panel, sizer=hbox, label="DDC")
+
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital down converter.
+ """
+ r = self.u.tune(0, self.subdev, target_freq)
+
+ if r:
+ self.myform['freq'].set_value(target_freq) # update displayed value
+ if self.show_debug_info:
+ self.myform['baseband'].set_value(r.baseband_freq)
+ self.myform['ddc'].set_value(r.dxc_freq)
+ return True
+
+ return False
+
+ def set_gain(self, gain):
+ self.myform['gain'].set_value(gain) # update displayed value
+ self.subdev.set_gain(gain)
+
+ def set_decim(self, decim):
+ ok = self.u.set_decim_rate(decim)
+ if not ok:
+ print "set_decim failed"
+ input_rate = self.u.adc_freq() / self.u.decim_rate()
+ self.scope.set_sample_rate(input_rate)
+ if self.show_debug_info: # update displayed values
+ self.myform['decim'].set_value(self.u.decim_rate())
+ self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
+ return ok
+
+def main ():
+ app = stdgui.stdapp(app_flow_graph, "USRP FFT", nstatus=1)
+ app.MainLoop()
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/usrp_fft_old.py b/gnuradio-examples/python/usrp/usrp_fft_old.py
new file mode 100755
index 000000000..c0776ea5c
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_fft_old.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink, scopesink
+from optparse import OptionParser
+import wx
+
+class app_flow_graph (stdgui.gui_flow_graph):
+ def __init__(self, frame, panel, vbox, argv):
+ stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+ self.frame = frame
+ self.panel = panel
+
+ parser = OptionParser (option_class=eng_option)
+ parser.add_option ("-d", "--decim", type="int", default=16,
+ help="set fgpa decimation rate to DECIM")
+ parser.add_option ("-c", "--ddc-freq", type="eng_float", default=0,
+ help="set Rx DDC frequency to FREQ", metavar="FREQ")
+ parser.add_option ("-m", "--mux", type="intx", default=0x32103210,
+ help="set fpga FR_RX_MUX register to MUX")
+ parser.add_option ("-g", "--gain", type="eng_float", default=0,
+ help="set Rx PGA gain in dB (default 0 dB)")
+ (options, args) = parser.parse_args ()
+
+ self.u = usrp.source_c (0, options.decim, 1, gru.hexint(options.mux), 0)
+ self.u.set_rx_freq (0, options.ddc_freq)
+
+ self.u.set_pga (0, options.gain)
+ self.u.set_pga (1, options.gain)
+
+ self.u.set_verbose (0)
+
+ input_rate = self.u.adc_freq () / self.u.decim_rate ()
+
+ fft = fftsink.fft_sink_c (self, panel, fft_size=1024, sample_rate=input_rate)
+ #fft = fftsink.fft_sink_c (self, panel, fft_size=1024, fft_rate=50, sample_rate=input_rate)
+ self.connect (self.u, fft)
+ vbox.Add (fft.win, 10, wx.EXPAND)
+
+ if 0:
+ c2f_1 = gr.complex_to_float ()
+ scope = scopesink.scope_sink_f (self, panel, "Rx Data", input_rate)
+ vbox.Add (scope.win, 4, wx.EXPAND)
+
+ self.connect (self.u,c2f_1)
+ self.connect ((c2f_1, 0), (scope, 0))
+ self.connect ((c2f_1, 1), (scope, 1))
+
+ # build small control area at bottom
+ hbox = wx.BoxSizer (wx.HORIZONTAL)
+ hbox.Add ((1, 1), 1, wx.EXPAND)
+ hbox.Add (wx.StaticText (panel, -1, "Set ddc freq: "), 0, wx.ALIGN_CENTER)
+ self.tc_freq = wx.TextCtrl (panel, -1, "", style=wx.TE_PROCESS_ENTER)
+ hbox.Add (self.tc_freq, 0, wx.ALIGN_CENTER)
+ wx.EVT_TEXT_ENTER (self.tc_freq, self.tc_freq.GetId(), self.handle_text_enter)
+ hbox.Add ((1, 1), 1, wx.EXPAND)
+ # add it to the main vbox
+ vbox.Add (hbox, 0, wx.EXPAND)
+
+ self.update_status_bar ()
+
+ def handle_text_enter (self, event):
+ str = event.GetString ()
+ self.tc_freq.Clear ()
+ self.u.set_rx_freq (0, eng_notation.str_to_num (str))
+ self.update_status_bar ()
+
+ def update_status_bar (self):
+ ddc_freq = self.u.rx_freq (0)
+ decim_rate = self.u.decim_rate ()
+ sample_rate = self.u.adc_freq () / decim_rate
+ msg = "decim: %d %sS/s DDC: %s" % (
+ decim_rate,
+ eng_notation.num_to_str (sample_rate),
+ eng_notation.num_to_str (ddc_freq))
+
+ self.frame.GetStatusBar().SetStatusText (msg, 1)
+
+
+
+def main ():
+ app = stdgui.stdapp (app_flow_graph, "USRP FFT")
+ app.MainLoop ()
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py b/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py
new file mode 100755
index 000000000..3e930bbb5
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py
@@ -0,0 +1,491 @@
+#!/usr/bin/env python
+#
+# Copyright 2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+import math
+import sys
+import wx
+from optparse import OptionParser
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio import usrp
+from gnuradio import audio
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink, scopesink, slider, form
+import usrp_dbid
+
+from Numeric import convolve, array
+
+#import os
+#print "pid =", os.getpid()
+#raw_input('Press Enter to continue: ')
+
+# ////////////////////////////////////////////////////////////////////////
+# Control Stuff
+# ////////////////////////////////////////////////////////////////////////
+
+class ptt_graph(stdgui.gui_flow_graph):
+ def __init__(self, frame, panel, vbox, argv):
+ stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+ self.frame = frame
+ self.space_bar_pressed = False
+
+ parser = OptionParser (option_class=eng_option)
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+ help="select USRP Rx side A or B")
+ parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
+ help="select USRP Tx side A or B")
+ parser.add_option ("-f", "--freq", type="eng_float", default=442.1e6,
+ help="set Tx and Rx frequency to FREQ", metavar="FREQ")
+ parser.add_option ("-g", "--rx-gain", type="eng_float", default=None,
+ help="set rx gain [default=midpoint in dB]")
+ parser.add_option("-I", "--audio-input", type="string", default="",
+ help="pcm input device name. E.g., hw:0,0 or /dev/dsp")
+ parser.add_option("-O", "--audio-output", type="string", default="",
+ help="pcm output device name. E.g., hw:0,0 or /dev/dsp")
+ parser.add_option ("-N", "--no-gui", action="store_true", default=False)
+ (options, args) = parser.parse_args ()
+
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+
+ if options.freq < 1e6:
+ options.freq *= 1e6
+
+ self.txpath = transmit_path(self, options.tx_subdev_spec, options.audio_input)
+ self.rxpath = receive_path(self, options.rx_subdev_spec, options.rx_gain, options.audio_output)
+ self._build_gui(frame, panel, vbox, argv, options.no_gui)
+
+ self.set_transmit(False)
+ self.set_freq(options.freq)
+ self.set_rx_gain(self.rxpath.gain) # update gui
+ self.set_volume(self.rxpath.volume) # update gui
+ self.set_squelch(self.rxpath.threshold()) # update gui
+
+
+ def set_transmit(self, enabled):
+ self.txpath.set_enable(enabled)
+ self.rxpath.set_enable(not(enabled))
+ if enabled:
+ self.frame.SetStatusText ("Transmitter ON", 1)
+ else:
+ self.frame.SetStatusText ("Receiver ON", 1)
+
+
+ def set_rx_gain(self, gain):
+ self.myform['rx_gain'].set_value(gain) # update displayed value
+ self.rxpath.set_gain(gain)
+
+ def set_tx_gain(self, gain):
+ self.txpath.set_gain(gain)
+
+ def set_squelch(self, threshold):
+ self.rxpath.set_squelch(threshold)
+ self.myform['squelch'].set_value(self.rxpath.threshold())
+
+ def set_volume (self, vol):
+ self.rxpath.set_volume(vol)
+ self.myform['volume'].set_value(self.rxpath.volume)
+ #self.update_status_bar ()
+
+ def set_freq(self, freq):
+ r1 = self.txpath.set_freq(freq)
+ r2 = self.rxpath.set_freq(freq)
+ #print "txpath.set_freq =", r1
+ #print "rxpath.set_freq =", r2
+ if r1 and r2:
+ self.myform['freq'].set_value(freq) # update displayed value
+ return r1 and r2
+
+ def _build_gui(self, frame, panel, vbox, argv, no_gui):
+
+ def _form_set_freq(kv):
+ return self.set_freq(kv['freq'])
+
+ self.panel = panel
+
+ # FIXME This REALLY needs to be replaced with a hand-crafted button
+ # that sends both button down and button up events
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((10,0), 1)
+ self.status_msg = wx.StaticText(panel, -1, "Press Space Bar to Transmit")
+ of = self.status_msg.GetFont()
+ self.status_msg.SetFont(wx.Font(15, of.GetFamily(), of.GetStyle(), of.GetWeight()))
+ hbox.Add(self.status_msg, 0, wx.ALIGN_CENTER)
+ hbox.Add((10,0), 1)
+ vbox.Add(hbox, 0, wx.EXPAND | wx.ALIGN_CENTER)
+
+ panel.Bind(wx.EVT_KEY_DOWN, self._on_key_down)
+ panel.Bind(wx.EVT_KEY_UP, self._on_key_up)
+ panel.Bind(wx.EVT_KILL_FOCUS, self._on_kill_focus)
+ panel.SetFocus()
+
+ if 1 and not(no_gui):
+ rx_fft = fftsink.fft_sink_c (self, panel, title="Rx Input", fft_size=512,
+ sample_rate=self.rxpath.if_rate,
+ ref_level=80, y_per_div=20)
+ self.connect (self.rxpath.u, rx_fft)
+ vbox.Add (rx_fft.win, 1, wx.EXPAND)
+
+ if 1 and not(no_gui):
+ rx_fft = fftsink.fft_sink_c (self, panel, title="Post s/w DDC",
+ fft_size=512, sample_rate=self.rxpath.quad_rate,
+ ref_level=80, y_per_div=20)
+ self.connect (self.rxpath.ddc, rx_fft)
+ vbox.Add (rx_fft.win, 1, wx.EXPAND)
+
+ if 0 and not(no_gui):
+ foo = scopesink.scope_sink_f (self, panel, title="Squelch",
+ sample_rate=32000)
+ self.connect (self.rxpath.fmrx.div, (foo,0))
+ self.connect (self.rxpath.fmrx.gate, (foo,1))
+ self.connect (self.rxpath.fmrx.squelch_lpf, (foo,2))
+ vbox.Add (foo.win, 1, wx.EXPAND)
+
+ if 0 and not(no_gui):
+ tx_fft = fftsink.fft_sink_c (self, panel, title="Tx Output",
+ fft_size=512, sample_rate=self.txpath.usrp_rate)
+ self.connect (self.txpath.amp, tx_fft)
+ vbox.Add (tx_fft.win, 1, wx.EXPAND)
+
+
+ # add control area at the bottom
+
+ self.myform = myform = form.form()
+
+ # first row
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0, 0)
+ myform['freq'] = form.float_field(
+ parent=panel, sizer=hbox, label="Freq", weight=1,
+ callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+ hbox.Add((5,0), 0, 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+
+ # second row
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ myform['volume'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume",
+ weight=3, range=self.rxpath.volume_range(),
+ callback=self.set_volume)
+ hbox.Add((5,0), 0)
+ myform['squelch'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Squelch",
+ weight=3, range=self.rxpath.squelch_range(),
+ callback=self.set_squelch)
+ hbox.Add((5,0), 0)
+ myform['rx_gain'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Rx Gain",
+ weight=3, range=self.rxpath.subdev.gain_range(),
+ callback=self.set_rx_gain)
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+
+ self._build_subpanel(vbox)
+
+ def _build_subpanel(self, vbox_arg):
+ # build a secondary information panel (sometimes hidden)
+
+ # FIXME figure out how to have this be a subpanel that is always
+ # created, but has its visibility controlled by foo.Show(True/False)
+
+ #if not(self.show_debug_info):
+ # return
+
+ panel = self.panel
+ vbox = vbox_arg
+ myform = self.myform
+
+ #panel = wx.Panel(self.panel, -1)
+ #vbox = wx.BoxSizer(wx.VERTICAL)
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+ #myform['decim'] = form.static_float_field(
+ # parent=panel, sizer=hbox, label="Decim")
+
+ #hbox.Add((5,0), 1)
+ #myform['fs@usb'] = form.static_float_field(
+ # parent=panel, sizer=hbox, label="Fs@USB")
+
+ #hbox.Add((5,0), 1)
+ #myform['dbname'] = form.static_text_field(
+ # parent=panel, sizer=hbox)
+
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+
+ def _set_status_msg(self, msg, which=0):
+ self.frame.GetStatusBar().SetStatusText(msg, which)
+
+ def _on_key_down(self, evt):
+ # print "key_down:", evt.m_keyCode
+ if evt.m_keyCode == wx.WXK_SPACE and not(self.space_bar_pressed):
+ self.space_bar_pressed = True
+ self.set_transmit(True)
+
+ def _on_key_up(self, evt):
+ # print "key_up", evt.m_keyCode
+ if evt.m_keyCode == wx.WXK_SPACE:
+ self.space_bar_pressed = False
+ self.set_transmit(False)
+
+ def _on_kill_focus(self, evt):
+ # if we lose the keyboard focus, turn off the transmitter
+ self.space_bar_pressed = False
+ self.set_transmit(False)
+
+
+# ////////////////////////////////////////////////////////////////////////
+# Transmit Path
+# ////////////////////////////////////////////////////////////////////////
+
+class transmit_path(gr.hier_block):
+ def __init__(self, fg, subdev_spec, audio_input):
+
+ self.u = usrp.sink_c ()
+
+ dac_rate = self.u.dac_rate();
+ self.if_rate = 320e3 # 320 kS/s
+ self.usrp_interp = int(dac_rate // self.if_rate)
+ self.u.set_interp_rate(self.usrp_interp)
+ self.sw_interp = 10
+ self.audio_rate = self.if_rate // self.sw_interp # 32 kS/s
+
+ self.audio_gain = 10
+ self.normal_gain = 32000
+
+ self.audio = audio.source(int(self.audio_rate), audio_input)
+ self.audio_amp = gr.multiply_const_ff(self.audio_gain)
+
+ lpf = gr.firdes.low_pass (1, # gain
+ self.audio_rate, # sampling rate
+ 3800, # low pass cutoff freq
+ 300, # width of trans. band
+ gr.firdes.WIN_HANN) # filter type
+
+ hpf = gr.firdes.high_pass (1, # gain
+ self.audio_rate, # sampling rate
+ 325, # low pass cutoff freq
+ 50, # width of trans. band
+ gr.firdes.WIN_HANN) # filter type
+
+ audio_taps = convolve(array(lpf),array(hpf))
+ self.audio_filt = gr.fir_filter_fff(1,audio_taps)
+
+ self.pl = blks.ctcss_gen_f(fg, self.audio_rate,123.0)
+ self.add_pl = gr.add_ff()
+ fg.connect(self.pl,(self.add_pl,1))
+
+ self.fmtx = blks.nbfm_tx(fg, self.audio_rate, self.if_rate)
+ self.amp = gr.multiply_const_cc (self.normal_gain)
+
+ # determine the daughterboard subdevice we're using
+ if subdev_spec is None:
+ subdev_spec = usrp.pick_tx_subdevice(self.u)
+ self.u.set_mux(usrp.determine_tx_mux_value(self.u, subdev_spec))
+ self.subdev = usrp.selected_subdev(self.u, subdev_spec)
+ print "TX using", self.subdev.name()
+
+ fg.connect(self.audio, self.audio_amp, self.audio_filt,
+ (self.add_pl,0), self.fmtx, self.amp, self.u)
+
+ gr.hier_block.__init__(self, fg, None, None)
+
+ self.set_gain(self.subdev.gain_range()[1]) # set max Tx gain
+
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital up converter. Finally, we feed
+ any residual_freq to the s/w freq translater.
+ """
+ r = self.u.tune(self.subdev._which, self.subdev, target_freq)
+ if r:
+ # Use residual_freq in s/w freq translator
+ return True
+
+ return False
+
+ def set_gain(self, gain):
+ self.gain = gain
+ self.subdev.set_gain(gain)
+
+ def set_enable(self, enable):
+ self.subdev.set_enable(enable) # set H/W Tx enable
+ if enable:
+ self.amp.set_k (self.normal_gain)
+ else:
+ self.amp.set_k (0)
+
+
+
+# ////////////////////////////////////////////////////////////////////////
+# Receive Path
+# ////////////////////////////////////////////////////////////////////////
+
+class receive_path(gr.hier_block):
+ def __init__(self, fg, subdev_spec, gain, audio_output):
+
+ self.u = usrp.source_c ()
+ adc_rate = self.u.adc_rate()
+
+ self.if_rate = 256e3 # 256 kS/s
+ usrp_decim = int(adc_rate // self.if_rate)
+ if_decim = 4
+ self.u.set_decim_rate(usrp_decim)
+ self.quad_rate = self.if_rate // if_decim # 64 kS/s
+ audio_decim = 2
+ audio_rate = self.quad_rate // audio_decim # 32 kS/s
+
+ if subdev_spec is None:
+ subdev_spec = usrp.pick_rx_subdevice(self.u)
+ self.subdev = usrp.selected_subdev(self.u, subdev_spec)
+ print "RX using", self.subdev.name()
+
+ self.u.set_mux(usrp.determine_rx_mux_value(self.u, subdev_spec))
+
+ # Create filter to get actual channel we want
+ chan_coeffs = gr.firdes.low_pass (1.0, # gain
+ self.if_rate, # sampling rate
+ 13e3, # low pass cutoff freq
+ 4e3, # width of trans. band
+ gr.firdes.WIN_HANN) # filter type
+
+ print "len(rx_chan_coeffs) =", len(chan_coeffs)
+
+ # Decimating Channel filter with frequency translation
+ # complex in and out, float taps
+ self.ddc = gr.freq_xlating_fir_filter_ccf(if_decim, # decimation rate
+ chan_coeffs, # taps
+ 0, # frequency translation amount
+ self.if_rate) # input sample rate
+
+ # instantiate the guts of the single channel receiver
+ self.fmrx = blks.nbfm_rx(fg, audio_rate, self.quad_rate)
+
+ # standard squelch block
+ self.squelch = blks.standard_squelch(fg, audio_rate)
+
+ # audio gain / mute block
+ self._audio_gain = gr.multiply_const_ff(1.0)
+
+ # sound card as final sink
+ audio_sink = audio.sink (int(audio_rate), audio_output)
+
+ # now wire it all together
+ fg.connect (self.u, self.ddc, self.fmrx, self.squelch, self._audio_gain, audio_sink)
+ gr.hier_block.__init__(self, fg, self.u, audio_sink)
+
+ if gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.subdev.gain_range()
+ gain = float(g[0]+g[1])/2
+
+ self.enabled = True
+ self.set_gain(gain)
+ v = self.volume_range()
+ self.set_volume((v[0]+v[1])/2)
+ s = self.squelch_range()
+ self.set_squelch((s[0]+s[1])/2)
+
+
+ def volume_range(self):
+ return (-20.0, 0.0, 0.5)
+
+ def set_volume (self, vol):
+ g = self.volume_range()
+ self.volume = max(g[0], min(g[1], vol))
+ self._update_audio_gain()
+
+ def set_enable(self, enable):
+ self.enabled = enable
+ self._update_audio_gain()
+
+ def _update_audio_gain(self):
+ if self.enabled:
+ self._audio_gain.set_k(10**(self.volume/10))
+ else:
+ self._audio_gain.set_k(0)
+
+ def squelch_range(self):
+ return self.squelch.squelch_range()
+
+ def set_squelch(self, threshold):
+ print "SQL =", threshold
+ self.squelch.set_threshold(threshold)
+
+ def threshold(self):
+ return self.squelch.threshold()
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital down converter in the
+ FPGA. Finally, we feed any residual_freq to the s/w freq
+ translator.
+ """
+ r = self.u.tune(0, self.subdev, target_freq)
+ if r:
+ # Use residual_freq in s/w freq translater
+ # print "residual_freq =", r.residual_freq
+ self.ddc.set_center_freq(-r.residual_freq)
+ return True
+
+ return False
+
+ def set_gain(self, gain):
+ self.gain = gain
+ self.subdev.set_gain(gain)
+
+
+# ////////////////////////////////////////////////////////////////////////
+# Main
+# ////////////////////////////////////////////////////////////////////////
+
+def main():
+ app = stdgui.stdapp(ptt_graph, "NBFM Push to Talk")
+ app.MainLoop()
+
+if __name__ == '__main__':
+ main()
diff --git a/gnuradio-examples/python/usrp/usrp_nbfm_rcv.py b/gnuradio-examples/python/usrp/usrp_nbfm_rcv.py
new file mode 100755
index 000000000..018a5b76e
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_nbfm_rcv.py
@@ -0,0 +1,362 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import slider, powermate
+from gnuradio.wxgui import stdgui, fftsink, form
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+import wx
+
+
+#////////////////////////////////////////////////////////////////////////
+# Control Stuff
+#////////////////////////////////////////////////////////////////////////
+
+class my_graph (stdgui.gui_flow_graph):
+ def __init__(self,frame,panel,vbox,argv):
+ stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)
+
+ parser=OptionParser(option_class=eng_option)
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+ help="select USRP Rx side A or B (default=A)")
+ parser.add_option("-f", "--freq", type="eng_float", default=146.585e6,
+ help="set frequency to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=None,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option("-V", "--volume", type="eng_float", default=None,
+ help="set volume (default is midpoint)")
+ parser.add_option("-O", "--audio-output", type="string", default="",
+ help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp")
+ parser.add_option("-N", "--no-gui", action="store_true", default=False)
+
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+
+ if options.freq < 1e6:
+ options.freq *= 1e6
+
+ self.frame = frame
+ self.panel = panel
+
+ self.state = "FREQ"
+ self.freq = 0
+ self.freq_step = 25e3
+
+ self.rxpath = receive_path(self, options.rx_subdev_spec, options.gain, options.audio_output)
+
+ self._build_gui(vbox, options.no_gui)
+
+ # set initial values
+
+ if options.volume is not None:
+ self.set_volume(options.volume)
+
+ if not(self.set_freq(options.freq)):
+ self._set_status_msg("Failed to set initial frequency")
+
+ self.set_gain(self.rxpath.gain) # update gui
+ self.set_volume(self.rxpath.volume) # update gui
+ self.set_squelch(self.rxpath.threshold()) # update gui
+
+
+ def _set_status_msg(self, msg, which=0):
+ self.frame.GetStatusBar().SetStatusText(msg, which)
+
+
+ def _build_gui(self, vbox, no_gui):
+
+ def _form_set_freq(kv):
+ return self.set_freq(kv['freq'])
+
+
+ self.src_fft = None
+ if 1 and not(no_gui):
+ self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP",
+ fft_size=512, sample_rate=self.rxpath.if_rate,
+ ref_level=80, y_per_div=20)
+ self.connect (self.rxpath.u, self.src_fft)
+ vbox.Add (self.src_fft.win, 4, wx.EXPAND)
+
+ if 1 and not(no_gui):
+ rx_fft = fftsink.fft_sink_c (self, self.panel, title="Post s/w DDC",
+ fft_size=512, sample_rate=self.rxpath.quad_rate,
+ ref_level=80, y_per_div=20)
+ self.connect (self.rxpath.ddc, rx_fft)
+ vbox.Add (rx_fft.win, 4, wx.EXPAND)
+
+ if 1 and not(no_gui):
+ post_deemph_fft = fftsink.fft_sink_f (self, self.panel, title="Post Deemph",
+ fft_size=512, sample_rate=self.rxpath.audio_rate,
+ y_per_div=10, ref_level=-40)
+ self.connect (self.rxpath.fmrx.deemph, post_deemph_fft)
+ vbox.Add (post_deemph_fft.win, 4, wx.EXPAND)
+
+ if 0:
+ post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Filter",
+ fft_size=512, sample_rate=audio_rate,
+ y_per_div=10, ref_level=-40)
+ self.connect (self.guts.audio_filter, post_filt)
+ vbox.Add (fft_win4, 4, wx.EXPAND)
+
+
+ # control area form at bottom
+ self.myform = myform = form.form()
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+ myform['freq'] = form.float_field(
+ parent=self.panel, sizer=hbox, label="Freq", weight=1,
+ callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+ #hbox.Add((5,0), 0)
+ #myform['freq_slider'] = \
+ # form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3,
+ # range=(87.9e6, 108.1e6, 0.1e6),
+ # callback=self.set_freq)
+
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+
+ myform['volume'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume",
+ weight=3, range=self.volume_range(),
+ callback=self.set_volume)
+ hbox.Add((5,0), 0)
+ myform['squelch'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Squelch",
+ weight=3, range=self.rxpath.squelch_range(),
+ callback=self.set_squelch)
+ hbox.Add((5,0), 0)
+ myform['gain'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain",
+ weight=3, range=self.rxpath.subdev.gain_range(),
+ callback=self.set_gain)
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ try:
+ self.knob = powermate.powermate(self.frame)
+ self.rot = 0
+ powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate)
+ powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button)
+ except:
+ print "FYI: No Powermate or Contour Knob found"
+
+
+ def on_rotate (self, event):
+ self.rot += event.delta
+ if (self.state == "FREQ"):
+ if self.rot >= 3:
+ self.set_freq(self.freq + self.freq_step)
+ self.rot -= 3
+ elif self.rot <=-3:
+ self.set_freq(self.freq - self.freq_step)
+ self.rot += 3
+ else:
+ step = self.volume_range()[2]
+ if self.rot >= 3:
+ self.set_volume(self.rxpath.volume + step)
+ self.rot -= 3
+ elif self.rot <=-3:
+ self.set_volume(self.rxpath.volume - step)
+ self.rot += 3
+
+ def on_button (self, event):
+ if event.value == 0: # button up
+ return
+ self.rot = 0
+ if self.state == "FREQ":
+ self.state = "VOL"
+ else:
+ self.state = "FREQ"
+ self.update_status_bar ()
+
+
+ def set_squelch(self, threshold_in_db):
+ self.rxpath.set_squelch(threshold_in_db)
+ self.myform['squelch'].set_value(self.rxpath.threshold())
+
+ def set_volume (self, vol):
+ self.rxpath.set_volume(vol)
+ self.myform['volume'].set_value(self.rxpath.volume)
+ self.update_status_bar ()
+
+ def set_freq(self, target_freq):
+ r = self.rxpath.set_freq(target_freq)
+ if r:
+ self.freq = target_freq
+ self.myform['freq'].set_value(target_freq) # update displayed value
+ #self.myform['freq_slider'].set_value(target_freq) # update displayed value
+ self.update_status_bar()
+ self._set_status_msg("OK", 0)
+ return True
+
+ self._set_status_msg("Failed", 0)
+ return False
+
+ def set_gain(self, gain):
+ self.myform['gain'].set_value(gain) # update displayed value
+ self.rxpath.set_gain(gain)
+
+ def update_status_bar (self):
+ msg = "Volume:%r Setting:%s" % (self.rxpath.volume, self.state)
+ self._set_status_msg(msg, 1)
+ if self.src_fft:
+ self.src_fft.set_baseband_freq(self.freq)
+
+ def volume_range(self):
+ return (-20.0, 0.0, 0.5)
+
+
+#////////////////////////////////////////////////////////////////////////
+# Receive Path
+#////////////////////////////////////////////////////////////////////////
+
+USE_SIMPLE_SQUELCH = False
+
+class receive_path(gr.hier_block):
+ def __init__(self, fg, subdev_spec, gain, audio_output):
+
+ self.u = usrp.source_c ()
+ adc_rate = self.u.adc_rate()
+
+ self.if_rate = 256e3 # 256 kS/s
+ usrp_decim = int(adc_rate // self.if_rate)
+ if_decim = 4
+ self.u.set_decim_rate(usrp_decim)
+ self.quad_rate = self.if_rate // if_decim # 64 kS/s
+ audio_decim = 2
+ self.audio_rate = self.quad_rate // audio_decim # 32 kS/s
+
+
+ if subdev_spec is None:
+ subdev_spec = usrp.pick_rx_subdevice(self.u)
+ self.subdev = usrp.selected_subdev(self.u, subdev_spec)
+ print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+
+ self.u.set_mux(usrp.determine_rx_mux_value(self.u, subdev_spec))
+
+ # Create filter to get actual channel we want
+ chan_coeffs = gr.firdes.low_pass (1.0, # gain
+ self.if_rate, # sampling rate
+ 13e3, # low pass cutoff freq
+ 4e3, # width of trans. band
+ gr.firdes.WIN_HANN) # filter type
+
+ print "len(rx_chan_coeffs) =", len(chan_coeffs)
+
+ # Decimating Channel filter with frequency translation
+ # complex in and out, float taps
+ self.ddc = gr.freq_xlating_fir_filter_ccf(if_decim, # decimation rate
+ chan_coeffs, # taps
+ 0, # frequency translation amount
+ self.if_rate) # input sample rate
+
+ if USE_SIMPLE_SQUELCH:
+ self.squelch = gr.simple_squelch_cc(20)
+ else:
+ self.squelch = blks.standard_squelch(fg, self.audio_rate)
+
+ # instantiate the guts of the single channel receiver
+ self.fmrx = blks.nbfm_rx(fg, self.audio_rate, self.quad_rate)
+
+ # audio gain / mute block
+ self._audio_gain = gr.multiply_const_ff(1.0)
+
+ # sound card as final sink
+ audio_sink = audio.sink (int(self.audio_rate), audio_output)
+
+ # now wire it all together
+ if USE_SIMPLE_SQUELCH:
+ fg.connect (self.u, self.ddc, self.squelch, self.fmrx,
+ self._audio_gain, audio_sink)
+ else:
+ fg.connect (self.u, self.ddc, self.fmrx, self.squelch,
+ self._audio_gain, audio_sink)
+
+ gr.hier_block.__init__(self, fg, self.u, audio_sink)
+
+ if gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.subdev.gain_range()
+ gain = float(g[0]+g[1])/2
+
+ self.set_gain(gain)
+
+ v = self.volume_range()
+ self.set_volume((v[0]+v[1])/2)
+ s = self.squelch_range()
+ self.set_squelch((s[0]+s[1])/2)
+
+ def volume_range(self):
+ return (-20.0, 0.0, 0.5)
+
+ def set_volume (self, vol):
+ g = self.volume_range()
+ self.volume = max(g[0], min(g[1], vol))
+ self._update_audio_gain()
+
+ def _update_audio_gain(self):
+ self._audio_gain.set_k(10**(self.volume/10))
+
+ def squelch_range(self):
+ r = self.squelch.squelch_range()
+ #print "squelch_range: ", r
+ return r
+
+ def set_squelch(self, threshold):
+ #print "SQL =", threshold
+ self.squelch.set_threshold(threshold)
+
+ def threshold(self):
+ t = self.squelch.threshold()
+ #print "t =", t
+ return t
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital down converter in the
+ FPGA. Finally, we feed any residual_freq to the s/w freq
+ translator.
+ """
+
+ r = usrp.tune(self.u, 0, self.subdev, target_freq)
+ if r:
+ # Use residual_freq in s/w freq translater
+ # print "residual_freq =", r.residual_freq
+ self.ddc.set_center_freq(-r.residual_freq)
+ return True
+
+ return False
+
+ def set_gain(self, gain):
+ self.gain = gain
+ self.subdev.set_gain(gain)
+
+
+# ////////////////////////////////////////////////////////////////////////
+# Main
+# ////////////////////////////////////////////////////////////////////////
+
+if __name__ == '__main__':
+ app = stdgui.stdapp (my_graph, "USRP NBFM RX")
+ app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/usrp_oscope.py b/gnuradio-examples/python/usrp/usrp_oscope.py
new file mode 100755
index 000000000..f4469f996
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_oscope.py
@@ -0,0 +1,252 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+# print "Loading revised usrp_oscope with additional options for scopesink..."
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider
+from optparse import OptionParser
+import wx
+import sys
+
+
+def pick_subdevice(u):
+ """
+ The user didn't specify a subdevice on the command line.
+ If there's a daughterboard on A, select A.
+ If there's a daughterboard on B, select B.
+ Otherwise, select A.
+ """
+ if u.db[0][0].dbid() >= 0: # dbid is < 0 if there's no d'board or a problem
+ return (0, 0)
+ if u.db[1][0].dbid() >= 0:
+ return (1, 0)
+ return (0, 0)
+
+
+class app_flow_graph(stdgui.gui_flow_graph):
+ def __init__(self, frame, panel, vbox, argv):
+ stdgui.gui_flow_graph.__init__(self)
+
+ self.frame = frame
+ self.panel = panel
+
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+ help="select USRP Rx side A or B (default=first one with a daughterboard)")
+ parser.add_option("-d", "--decim", type="int", default=16,
+ help="set fgpa decimation rate to DECIM [default=%default]")
+ parser.add_option("-f", "--freq", type="eng_float", default=None,
+ help="set frequency to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=None,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option("-8", "--width-8", action="store_true", default=False,
+ help="Enable 8-bit samples across USB")
+ parser.add_option("-n", "--frame-decim", type="int", default=1,
+ help="set oscope frame decimation factor to n [default=1]")
+ parser.add_option("-v", "--v-scale", type="eng_float", default=1000,
+ help="set oscope initial V/div to SCALE [default=%default]")
+ parser.add_option("-t", "--t-scale", type="eng_float", default=49e-6,
+ help="set oscope initial s/div to SCALE [default=50us]")
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+
+ self.show_debug_info = True
+
+ # build the graph
+
+ self.u = usrp.source_c(decim_rate=options.decim)
+ if options.rx_subdev_spec is None:
+ options.rx_subdev_spec = pick_subdevice(self.u)
+ self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+
+ if options.width_8:
+ width = 8
+ shift = 8
+ format = self.u.make_format(width, shift)
+ #print "format =", hex(format)
+ r = self.u.set_format(format)
+ #print "set_format =", r
+
+ # determine the daughterboard subdevice we're using
+ self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+
+ input_rate = self.u.adc_freq() / self.u.decim_rate()
+
+ self.scope = scopesink.scope_sink_c(self, panel, sample_rate=input_rate,
+ frame_decim=options.frame_decim,
+ v_scale=options.v_scale,
+ t_scale=options.t_scale)
+ self.connect(self.u, self.scope)
+
+ self._build_gui(vbox)
+
+ # set initial values
+
+ if options.gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.subdev.gain_range()
+ options.gain = float(g[0]+g[1])/2
+
+ if options.freq is None:
+ # if no freq was specified, use the mid-point
+ r = self.subdev.freq_range()
+ options.freq = float(r[0]+r[1])/2
+
+ self.set_gain(options.gain)
+
+ if self.show_debug_info:
+ self.myform['decim'].set_value(self.u.decim_rate())
+ self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
+ self.myform['dbname'].set_value(self.subdev.name())
+ self.myform['baseband'].set_value(0)
+ self.myform['ddc'].set_value(0)
+
+ if not(self.set_freq(options.freq)):
+ self._set_status_msg("Failed to set initial frequency")
+
+
+ def _set_status_msg(self, msg):
+ self.frame.GetStatusBar().SetStatusText(msg, 0)
+
+ def _build_gui(self, vbox):
+
+ def _form_set_freq(kv):
+ return self.set_freq(kv['freq'])
+
+ vbox.Add(self.scope.win, 10, wx.EXPAND)
+
+ # add control area at the bottom
+ self.myform = myform = form.form()
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0, 0)
+ myform['freq'] = form.float_field(
+ parent=self.panel, sizer=hbox, label="Center freq", weight=1,
+ callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+ hbox.Add((5,0), 0, 0)
+ g = self.subdev.gain_range()
+ myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain",
+ weight=3,
+ min=int(g[0]), max=int(g[1]),
+ callback=self.set_gain)
+
+ hbox.Add((5,0), 0, 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ self._build_subpanel(vbox)
+
+ def _build_subpanel(self, vbox_arg):
+ # build a secondary information panel (sometimes hidden)
+
+ # FIXME figure out how to have this be a subpanel that is always
+ # created, but has its visibility controlled by foo.Show(True/False)
+
+ def _form_set_decim(kv):
+ return self.set_decim(kv['decim'])
+
+ if not(self.show_debug_info):
+ return
+
+ panel = self.panel
+ vbox = vbox_arg
+ myform = self.myform
+
+ #panel = wx.Panel(self.panel, -1)
+ #vbox = wx.BoxSizer(wx.VERTICAL)
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+
+ myform['decim'] = form.int_field(
+ parent=panel, sizer=hbox, label="Decim",
+ callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg))
+
+ hbox.Add((5,0), 1)
+ myform['fs@usb'] = form.static_float_field(
+ parent=panel, sizer=hbox, label="Fs@USB")
+
+ hbox.Add((5,0), 1)
+ myform['dbname'] = form.static_text_field(
+ parent=panel, sizer=hbox)
+
+ hbox.Add((5,0), 1)
+ myform['baseband'] = form.static_float_field(
+ parent=panel, sizer=hbox, label="Analog BB")
+
+ hbox.Add((5,0), 1)
+ myform['ddc'] = form.static_float_field(
+ parent=panel, sizer=hbox, label="DDC")
+
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital down converter.
+ """
+ r = usrp.tune(self.u, 0, self.subdev, target_freq)
+
+ if r:
+ self.myform['freq'].set_value(target_freq) # update displayed value
+ if self.show_debug_info:
+ self.myform['baseband'].set_value(r.baseband_freq)
+ self.myform['ddc'].set_value(r.dxc_freq)
+ return True
+
+ return False
+
+ def set_gain(self, gain):
+ self.myform['gain'].set_value(gain) # update displayed value
+ self.subdev.set_gain(gain)
+
+ def set_decim(self, decim):
+ ok = self.u.set_decim_rate(decim)
+ if not ok:
+ print "set_decim failed"
+ input_rate = self.u.adc_freq() / self.u.decim_rate()
+ self.scope.set_sample_rate(input_rate)
+ if self.show_debug_info: # update displayed values
+ self.myform['decim'].set_value(self.u.decim_rate())
+ self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
+ return ok
+
+def main ():
+ app = stdgui.stdapp(app_flow_graph, "USRP O'scope", nstatus=1)
+ app.MainLoop()
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/usrp_rx_cfile.py b/gnuradio-examples/python/usrp/usrp_rx_cfile.py
new file mode 100755
index 000000000..306e101d3
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_rx_cfile.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+
+"""
+Read samples from the USRP and write to file formatted as binary
+outputs single precision complex float values or complex short values (interleaved 16 bit signed short integers).
+
+"""
+
+from gnuradio import gr, eng_notation
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class my_graph(gr.flow_graph):
+
+ def __init__(self):
+ gr.flow_graph.__init__(self)
+
+ usage="%prog: [options] output_filename"
+ parser = OptionParser(option_class=eng_option, usage=usage)
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0),
+ help="select USRP Rx side A or B (default=A)")
+ parser.add_option("-d", "--decim", type="int", default=16,
+ help="set fgpa decimation rate to DECIM [default=%default]")
+ parser.add_option("-f", "--freq", type="eng_float", default=None,
+ help="set frequency to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=None,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option("-8", "--width-8", action="store_true", default=False,
+ help="Enable 8-bit samples across USB")
+ parser.add_option( "--no-hb", action="store_true", default=False,
+ help="don't use halfband filter in usrp")
+ parser.add_option( "-s","--output-shorts", action="store_true", default=False,
+ help="output interleaved shorts in stead of complex floats")
+ parser.add_option("-N", "--nsamples", type="eng_float", default=None,
+ help="number of samples to collect [default=+inf]")
+ (options, args) = parser.parse_args ()
+ if len(args) != 1:
+ parser.print_help()
+ raise SystemExit, 1
+ filename = args[0]
+
+ if options.freq is None:
+ parser.print_help()
+ sys.stderr.write('You must specify the frequency with -f FREQ\n');
+ raise SystemExit, 1
+
+ # build the graph
+ if options.no_hb or (options.decim<8):
+ self.fpga_filename="std_4rx_0tx.rbf" #Min decimation of this firmware is 4. contains 4 Rx paths without halfbands and 0 tx paths.
+ if options.output_shorts:
+ self.u = usrp.source_s(decim_rate=options.decim,fpga_filename=self.fpga_filename)
+ else:
+ self.u = usrp.source_c(decim_rate=options.decim,fpga_filename=self.fpga_filename)
+ else:
+ #standard fpga firmware "std_2rxhb_2tx.rbf" contains 2 Rx paths with halfband filters and 2 tx paths (the default) min decimation 8
+ if options.output_shorts:
+ self.u = usrp.source_s(decim_rate=options.decim)
+ else:
+ self.u = usrp.source_c(decim_rate=options.decim)
+ if options.width_8:
+ sample_width = 8
+ sample_shift = 8
+ format = self.u.make_format(sample_width, sample_shift)
+ r = self.u.set_format(format)
+ if options.output_shorts:
+ self.dst = gr.file_sink(gr.sizeof_short, filename)
+ else:
+ self.dst = gr.file_sink(gr.sizeof_gr_complex, filename)
+ if options.nsamples is None:
+ self.connect(self.u, self.dst)
+ else:
+ if options.output_shorts:
+ self.head = gr.head(gr.sizeof_short, int(options.nsamples)*2)
+ else:
+ self.head = gr.head(gr.sizeof_gr_complex, int(options.nsamples))
+ self.connect(self.u, self.head, self.dst)
+
+ if options.rx_subdev_spec is None:
+ options.rx_subdev_spec = usrp.pick_rx_subdevice(self.u)
+ self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+
+ # determine the daughterboard subdevice we're using
+ self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+ print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+ input_rate = self.u.adc_freq() / self.u.decim_rate()
+ print "USB sample rate %s" % (eng_notation.num_to_str(input_rate))
+
+ if options.gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.subdev.gain_range()
+ options.gain = float(g[0]+g[1])/2
+
+ self.subdev.set_gain(options.gain)
+
+ r = self.u.tune(0, self.subdev, options.freq)
+ if not r:
+ sys.stderr.write('Failed to set frequency\n')
+ raise SystemExit, 1
+
+
+if __name__ == '__main__':
+ try:
+ my_graph().run()
+ except KeyboardInterrupt:
+ pass
diff --git a/gnuradio-examples/python/usrp/usrp_rx_nogui.py b/gnuradio-examples/python/usrp/usrp_rx_nogui.py
new file mode 100755
index 000000000..b33d626e2
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_rx_nogui.py
@@ -0,0 +1,186 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, usrp, optfir, audio, eng_notation, blks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+"""
+This example application demonstrates receiving and demodulating
+different types of signals using the USRP.
+
+A receive chain is built up of the following signal processing
+blocks:
+
+USRP - Daughter board source generating complex baseband signal.
+CHAN - Low pass filter to select channel bandwidth
+RFSQL - RF squelch zeroing output when input power below threshold
+AGC - Automatic gain control leveling signal at [-1.0, +1.0]
+DEMOD - Demodulation block appropriate to selected signal type.
+ This converts the complex baseband to real audio frequencies,
+ and applies an appropriate low pass decimating filter.
+CTCSS - Optional tone squelch zeroing output when tone is not present.
+RSAMP - Resampler block to convert audio sample rate to user specified
+ sound card output rate.
+AUDIO - Audio sink for playing final output to speakers.
+
+The following are required command line parameters:
+
+-f FREQ USRP receive frequency
+-m MOD Modulation type, select from AM, FM, or WFM
+
+The following are optional command line parameters:
+
+-R SUBDEV Daughter board specification, defaults to first found
+-c FREQ Calibration offset. Gets added to receive frequency.
+ Defaults to 0.0 Hz.
+-g GAIN Daughterboard gain setting. Defaults to mid-range.
+-o RATE Sound card output rate. Defaults to 32000. Useful if
+ your sound card only accepts particular sample rates.
+-r RFSQL RF squelch in db. Defaults to -50.0.
+-p FREQ CTCSS frequency. Opens squelch when tone is present.
+
+Once the program is running, ctrl-break (Ctrl-C) stops operation.
+
+Please see fm_demod.py and am_demod.py for details of the demodulation
+blocks.
+"""
+
+# (usrp_decim, channel_decim, audio_decim, channel_pass, channel_stop, demod)
+demod_params = {
+ 'AM' : (250, 16, 1, 5000, 8000, blks.demod_10k0a3e_cf),
+ 'FM' : (250, 8, 4, 8000, 9000, blks.demod_20k0f3e_cf),
+ 'WFM' : (250, 1, 8, 90000, 100000, blks.demod_200kf3e_cf)
+ }
+
+class usrp_source_c(gr.hier_block):
+ """
+ Create a USRP source object supplying complex floats.
+
+ Selects user supplied subdevice or chooses first available one.
+
+ Calibration value is the offset from the tuned frequency to
+ the actual frequency.
+ """
+ def __init__(self, fg, subdev_spec, decim, gain=None, calibration=0.0):
+ self._decim = decim
+ self._src = usrp.source_c()
+ if subdev_spec is None:
+ subdev_spec = usrp.pick_rx_subdevice(self._src)
+ self._subdev = usrp.selected_subdev(self._src, subdev_spec)
+ self._src.set_mux(usrp.determine_rx_mux_value(self._src, subdev_spec))
+ self._src.set_decim_rate(self._decim)
+
+ # If no gain specified, set to midrange
+ if gain is None:
+ g = self._subdev.gain_range()
+ gain = (g[0]+g[1])/2.0
+
+ self._subdev.set_gain(gain)
+ self._cal = calibration
+ gr.hier_block.__init__(self, fg, self._src, self._src)
+
+ def tune(self, freq):
+ result = usrp.tune(self._src, 0, self._subdev, freq+self._cal)
+ # TODO: deal with residual
+
+ def rate(self):
+ return self._src.adc_rate()/self._decim
+
+class app_flow_graph(gr.flow_graph):
+ def __init__(self, options, args):
+ gr.flow_graph.__init__(self)
+ self.options = options
+ self.args = args
+
+ (usrp_decim, channel_decim, audio_decim,
+ channel_pass, channel_stop, demod) = demod_params[options.modulation]
+
+ USRP = usrp_source_c(self, # Flow graph
+ options.rx_subdev_spec, # Daugherboard spec
+ usrp_decim, # IF decimation ratio
+ options.gain, # Receiver gain
+ options.calibration) # Frequency offset
+ USRP.tune(options.frequency)
+
+ if_rate = USRP.rate()
+ channel_rate = if_rate // channel_decim
+ audio_rate = channel_rate // audio_decim
+
+ CHAN_taps = optfir.low_pass(1.0, # Filter gain
+ if_rate, # Sample rate
+ channel_pass, # One sided modulation bandwidth
+ channel_stop, # One sided channel bandwidth
+ 0.1, # Passband ripple
+ 60) # Stopband attenuation
+
+ CHAN = gr.freq_xlating_fir_filter_ccf(channel_decim, # Decimation rate
+ CHAN_taps, # Filter taps
+ 0.0, # Offset frequency
+ if_rate) # Sample rate
+
+ RFSQL = gr.pwr_squelch_cc(options.rf_squelch, # Power threshold
+ 125.0/channel_rate, # Time constant
+ channel_rate/20, # 50ms rise/fall
+ False) # Zero, not gate output
+
+ AGC = gr.agc_cc(1.0/channel_rate, # Time constant
+ 1.0, # Reference power
+ 1.0, # Initial gain
+ 1.0) # Maximum gain
+
+ DEMOD = demod(self, channel_rate, audio_decim)
+
+ # From RF to audio
+ self.connect(USRP, CHAN, RFSQL, AGC, DEMOD)
+
+ # Optionally add CTCSS and RSAMP if needed
+ tail = DEMOD
+ if options.ctcss != None and options.ctcss > 60.0:
+ CTCSS = gr.ctcss_squelch_ff(audio_rate, # Sample rate
+ options.ctcss) # Squelch tone
+ self.connect(DEMOD, CTCSS)
+ tail = CTCSS
+
+ if options.output_rate != audio_rate:
+ out_lcm = gru.lcm(audio_rate, options.output_rate)
+ out_interp = int(out_lcm // audio_rate)
+ out_decim = int(out_lcm // options.output_rate)
+ RSAMP = blks.rational_resampler_fff(self, out_interp, out_decim)
+ self.connect(tail, RSAMP)
+ tail = RSAMP
+
+ # Send to default audio output
+ AUDIO = audio.sink(options.output_rate, "")
+ self.connect(tail, AUDIO)
+
+def main():
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-f", "--frequency", type="eng_float",
+ help="set receive frequency to Hz", metavar="Hz")
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev",
+ help="select USRP Rx side A or B", metavar="SUBDEV")
+ parser.add_option("-c", "--calibration", type="eng_float", default=0.0,
+ help="set frequency offset to Hz", metavar="Hz")
+ parser.add_option("-g", "--gain", type="int", default=None,
+ help="set RF gain", metavar="dB")
+ parser.add_option("-m", "--modulation", type="choice", choices=('AM','FM','WFM'),
+ help="set modulation type (AM,FM)", metavar="TYPE")
+ parser.add_option("-o", "--output-rate", type="int", default=32000,
+ help="set audio output rate to RATE", metavar="RATE")
+ parser.add_option("-r", "--rf-squelch", type="eng_float", default=-50.0,
+ help="set RF squelch to dB", metavar="dB")
+ parser.add_option("-p", "--ctcss", type="float",
+ help="set CTCSS squelch to FREQ", metavar="FREQ")
+ (options, args) = parser.parse_args()
+
+ if options.frequency < 1e6:
+ options.frequency *= 1e6
+
+ fg = app_flow_graph(options, args)
+ try:
+ fg.run()
+ except KeyboardInterrupt:
+ pass
+
+if __name__ == "__main__":
+ main()
diff --git a/gnuradio-examples/python/usrp/usrp_siggen.py b/gnuradio-examples/python/usrp/usrp_siggen.py
new file mode 100755
index 000000000..59e01e0a9
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_siggen.py
@@ -0,0 +1,180 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from gnuradio import eng_notation
+from optparse import OptionParser
+import sys
+
+
+class my_graph(gr.flow_graph):
+ def __init__ (self):
+ gr.flow_graph.__init__(self)
+
+ # controllable values
+ self.interp = 64
+ self.waveform_type = gr.GR_SIN_WAVE
+ self.waveform_ampl = 16000
+ self.waveform_freq = 100.12345e3
+ self.waveform_offset = 0
+ self._instantiate_blocks ()
+ self.set_waveform_type (self.waveform_type)
+
+ def usb_freq (self):
+ return self.u.dac_freq() / self.interp
+
+ def usb_throughput (self):
+ return self.usb_freq () * 4
+
+ def set_waveform_type (self, type):
+ '''
+ valid waveform types are: gr.GR_SIN_WAVE, gr.GR_CONST_WAVE,
+ gr.GR_UNIFORM and gr.GR_GAUSSIAN
+ '''
+ self._configure_graph (type)
+ self.waveform_type = type
+
+ def set_waveform_ampl (self, ampl):
+ self.waveform_ampl = ampl
+ self.siggen.set_amplitude (ampl)
+ self.noisegen.set_amplitude (ampl)
+
+ def set_waveform_freq (self, freq):
+ self.waveform_freq = freq
+ self.siggen.set_frequency (freq)
+
+ def set_waveform_offset (self, offset):
+ self.waveform_offset = offset
+ self.siggen.set_offset (offset)
+
+ def set_interpolator (self, interp):
+ self.interp = interp
+ self.siggen.set_sampling_freq (self.usb_freq ())
+ self.u.set_interp_rate (interp)
+
+ def _instantiate_blocks (self):
+ self.src = None
+ self.u = usrp.sink_c (0, self.interp)
+
+ self.siggen = gr.sig_source_c (self.usb_freq (),
+ gr.GR_SIN_WAVE,
+ self.waveform_freq,
+ self.waveform_ampl,
+ self.waveform_offset)
+
+ self.noisegen = gr.noise_source_c (gr.GR_UNIFORM,
+ self.waveform_ampl)
+
+ # self.file_sink = gr.file_sink (gr.sizeof_gr_complex, "siggen.dat")
+
+ def _configure_graph (self, type):
+ was_running = self.is_running ()
+ if was_running:
+ self.stop ()
+ self.disconnect_all ()
+ if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE:
+ self.connect (self.siggen, self.u)
+ # self.connect (self.siggen, self.file_sink)
+ self.siggen.set_waveform (type)
+ self.src = self.siggen
+ elif type == gr.GR_UNIFORM or type == gr.GR_GAUSSIAN:
+ self.connect (self.noisegen, self.u)
+ self.noisegen.set_type (type)
+ self.src = self.noisegen
+ else:
+ raise ValueError, type
+ if was_running:
+ self.start ()
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital up converter.
+ """
+ r = self.u.tune(self.subdev._which, self.subdev, target_freq)
+ if r:
+ print "r.baseband_freq =", eng_notation.num_to_str(r.baseband_freq)
+ print "r.dxc_freq =", eng_notation.num_to_str(r.dxc_freq)
+ print "r.residual_freq =", eng_notation.num_to_str(r.residual_freq)
+ print "r.inverted =", r.inverted
+ return True
+
+ return False
+
+
+
+def main ():
+ parser = OptionParser (option_class=eng_option)
+ parser.add_option ("-T", "--tx-subdev-spec", type="subdev", default=(0, 0),
+ help="select USRP Tx side A or B")
+ parser.add_option ("-f", "--rf-freq", type="eng_float", default=None,
+ help="set RF center frequency to FREQ")
+ parser.add_option ("-i", "--interp", type="int", default=64,
+ help="set fgpa interpolation rate to INTERP")
+
+ parser.add_option ("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE,
+ help="generate a complex sinusoid [default]", default=gr.GR_SIN_WAVE)
+ parser.add_option ("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE,
+ help="generate a constant output")
+ parser.add_option ("--gaussian", dest="type", action="store_const", const=gr.GR_GAUSSIAN,
+ help="generate Gaussian random output")
+ parser.add_option ("--uniform", dest="type", action="store_const", const=gr.GR_UNIFORM,
+ help="generate Uniform random output")
+
+ parser.add_option ("-w", "--waveform-freq", type="eng_float", default=100e3,
+ help="set waveform frequency to FREQ")
+ parser.add_option ("-a", "--amplitude", type="eng_float", default=16e3,
+ help="set waveform amplitude to AMPLITUDE", metavar="AMPL")
+ parser.add_option ("-o", "--offset", type="eng_float", default=0,
+ help="set waveform offset to OFFSET")
+ (options, args) = parser.parse_args ()
+
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit
+
+ if options.rf_freq is None:
+ sys.stderr.write("usrp_siggen: must specify RF center frequency with -f RF_FREQ\n")
+ parser.print_help()
+ raise SystemExit
+
+ fg = my_graph()
+ fg.set_interpolator (options.interp)
+ fg.set_waveform_type (options.type)
+ fg.set_waveform_freq (options.waveform_freq)
+ fg.set_waveform_ampl (options.amplitude)
+ fg.set_waveform_offset (options.offset)
+
+ # determine the daughterboard subdevice we're using
+ if options.tx_subdev_spec is None:
+ options.tx_subdev_spec = usrp.pick_tx_subdevice(fg.u)
+
+ m = usrp.determine_tx_mux_value(fg.u, options.tx_subdev_spec)
+ #print "mux = %#04x" % (m,)
+ fg.u.set_mux(m)
+ fg.subdev = usrp.selected_subdev(fg.u, options.tx_subdev_spec)
+ print "Using TX d'board %s" % (fg.subdev.side_and_name(),)
+
+ fg.subdev.set_gain(fg.subdev.gain_range()[1]) # set max Tx gain
+
+ if not fg.set_freq(options.rf_freq):
+ sys.stderr.write('Failed to set RF frequency\n')
+ raise SystemExit
+
+ fg.subdev.set_enable(True) # enable transmitter
+
+ try:
+ fg.run()
+ except KeyboardInterrupt:
+ pass
+
+if __name__ == '__main__':
+ main ()
diff --git a/gnuradio-examples/python/usrp/usrp_tv_rcv.py b/gnuradio-examples/python/usrp/usrp_tv_rcv.py
new file mode 100755
index 000000000..ed78273a7
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_tv_rcv.py
@@ -0,0 +1,394 @@
+#!/usr/bin/env python
+"""
+Realtime capture and display of analog Tv stations.
+Can also use a file as source or sink
+When you use an output file you can show the results frame-by-frame using ImageMagick
+When you want to use the realtime sdl display window you must first install gr-video-sdl (is in gnuradio cvs).
+When you use a file source, in stead of the usrp, make sure you capture interleaved shorts.
+(Use usrp_rx_file.py, or use usrp_rx_cfile.py --output-shorts if you have a recent enough usrp_rx_cfile.py)
+There is no synchronisation yet. The sync blocks are in development but not yet in cvs.
+
+"""
+from gnuradio import gr, gru, eng_notation, optfir
+try:
+ from gnuradio import video_sdl
+except:
+ print "FYI: gr-video-sdl is not installed"
+ print "realtime SDL video output window will not be available"
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import slider, powermate
+from gnuradio.wxgui import stdgui, fftsink, form
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+import wx
+
+# To debug, insert this in your test code...
+#import os
+#print 'Blocked waiting for GDB attach (pid = %d)' % (os.getpid(),)
+#raw_input ('Press Enter to continue: ')
+# remainder of your test code follows...
+
+def pick_subdevice(u):
+ """
+ The user didn't specify a subdevice on the command line.
+ Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
+
+ @return a subdev_spec
+ """
+ return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
+ usrp_dbid.TV_RX_REV_2,
+ usrp_dbid.BASIC_RX))
+
+
+class tv_rx_graph (stdgui.gui_flow_graph):
+ def __init__(self,frame,panel,vbox,argv):
+ stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)
+
+ usage="%prog: [options] [input_filename]. \n If you don't specify an input filename the usrp will be used as source\n " \
+ "Make sure your input capture file containes interleaved shorts not complex floats"
+ parser=OptionParser(option_class=eng_option)
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+ help="select USRP Rx side A or B (default=A)")
+ parser.add_option("-d", "--decim", type="int", default=64,
+ help="set fgpa decimation rate to DECIM [default=%default]")
+ parser.add_option("-f", "--freq", type="eng_float", default=519.25e6,
+ help="set frequency to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=None,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option("-c", "--contrast", type="eng_float", default=1.0,
+ help="set contrast (default is 1.0)")
+ parser.add_option("-b", "--brightness", type="eng_float", default=0.0,
+ help="set brightness (default is 0)")
+ parser.add_option("-8", "--width-8", action="store_true", default=False,
+ help="Enable 8-bit samples across USB")
+ parser.add_option("-p", "--pal", action="store_true", default=False,
+ help="PAL video format (this is the default)")
+ parser.add_option("-n", "--ntsc", action="store_true", default=False,
+ help="NTSC video format")
+ parser.add_option("-o", "--out-filename", type="string", default="sdl",
+ help="For example out_raw_uchar.gray. If you don't specify an output filename you will get a video_sink_sdl realtime output window. You then need to have gr-video-sdl installed)")
+ parser.add_option("-r", "--repeat", action="store_false", default=True,
+ help="repeat file in a loop")
+ parser.add_option("-N", "--no-hb", action="store_true", default=False,
+ help="don't use halfband filter in usrp")
+
+ (options, args) = parser.parse_args()
+ if not ((len(args) == 1) or (len(args) == 0)):
+ parser.print_help()
+ sys.exit(1)
+
+ if len(args) == 1:
+ filename = args[0]
+ else:
+ filename = None
+
+ self.frame = frame
+ self.panel = panel
+
+ self.contrast = options.contrast
+ self.brightness = options.brightness
+ self.state = "FREQ"
+ self.freq = 0
+
+ # build graph
+
+ self.u=None
+
+ usrp_decim = options.decim # 32
+
+ if not (options.out_filename=="sdl"):
+ options.repeat=False
+
+ if not ((filename is None) or (filename=="usrp")):
+ self.filesource = gr.file_source(gr.sizeof_short,filename,options.repeat) # file is data source
+ self.istoc = gr.interleaved_short_to_complex()
+ self.connect(self.filesource,self.istoc)
+ adc_rate=64e6
+ self.src=self.istoc
+ options.gain=0.0
+ self.gain=0.0
+ else:
+ if options.no_hb or (options.decim<8):
+ self.fpga_filename="std_4rx_0tx.rbf" #contains 4 Rx paths without halfbands and 0 tx paths
+ else:
+ self.fpga_filename="std_2rxhb_2tx.rbf" # contains 2 Rx paths with halfband filters and 2 tx paths (the default)
+ self.u = usrp.source_c(0,fpga_filename=self.fpga_filename) # usrp is data source
+ if options.width_8:
+ sample_width = 8
+ sample_shift = 8
+ format = self.u.make_format(sample_width, sample_shift)
+ r = self.u.set_format(format)
+ adc_rate = self.u.adc_rate() # 64 MS/s
+ self.u.set_decim_rate(usrp_decim)
+ if options.rx_subdev_spec is None:
+ options.rx_subdev_spec = pick_subdevice(self.u)
+ self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+ self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+ print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+ if options.gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.subdev.gain_range()
+ options.gain = float(g[0]+g[1])/2
+ self.src=self.u
+
+ usrp_rate = adc_rate / usrp_decim # 320 kS/s
+
+ f2uc=gr.float_to_uchar()
+ # sdl window as final sink
+ if not (options.pal or options.ntsc):
+ options.pal=True #set default to PAL
+ if options.pal:
+ lines_per_frame=625.0
+ frames_per_sec=25.0
+ show_width=768
+ elif options.ntsc:
+ lines_per_frame=525.0
+ frames_per_sec=29.97002997
+ show_width=640
+ width=int(usrp_rate/(lines_per_frame*frames_per_sec))
+ height=int(lines_per_frame)
+
+ if (options.out_filename=="sdl"):
+ #Here comes the tv screen, you have to build and install gr-video-sdl for this (subproject of gnuradio, only in cvs for now)
+ try:
+ video_sink = video_sdl.sink_uc ( frames_per_sec, width, height,0,show_width,height)
+ except:
+ print "gr-video-sdl is not installed"
+ print "realtime \"sdl\" video output window is not available"
+ raise SystemExit, 1
+ self.dst=video_sink
+ else:
+ print "You can use the imagemagick display tool to show the resulting imagesequence"
+ print "use the following line to show the demodulated TV-signal:"
+ print "display -depth 8 -size " +str(width)+ "x" + str(height) + " gray:" + options.out_filename
+ print "(Use the spacebar to advance to next frames)"
+ options.repeat=False
+ file_sink=gr.file_sink(gr.sizeof_char, options.out_filename)
+ self.dst =file_sink
+
+ self.agc=gr.agc_cc(1e-7,1.0,1.0) #1e-7
+ self.am_demod = gr.complex_to_mag ()
+ self.set_blacklevel=gr.add_const_ff(0.0)
+ self.invert_and_scale = gr.multiply_const_ff (0.0) #-self.contrast *128.0*255.0/(200.0)
+
+ # now wire it all together
+ #sample_rate=options.width*options.height*options.framerate
+
+ process_type='do_no_sync'
+ if process_type=='do_no_sync':
+ self.connect (self.src, self.agc,self.am_demod,self.invert_and_scale, self.set_blacklevel,f2uc,self.dst)
+ elif process_type=='do_tv_sync_adv':
+ #defaults: gr.tv_sync_adv (double sampling_freq, unsigned int tv_format,bool output_active_video_only=false, bool do_invert=false, double wanted_black_level=0.0, double wanted_white_level=255.0, double avg_alpha=0.1, double initial_gain=1.0, double initial_offset=0.0,bool debug=false)
+ self.tv_sync_adv=gr.tv_sync_adv(usrp_rate,0,False,False,0.0,255.0,0.01,1.0,0.0,False) #note, this block is not yet in cvs
+ self.connect (self.src, self.am_demod,self.invert_and_scale,self.tv_sync_adv,s2f,f2uc,self.dst)
+ elif process_type=='do_nullsink':
+ #self.connect (self.src, self.am_demod,self.invert_and_scale,f2uc,video_sink)
+ c2r=gr.complex_to_real()
+ nullsink=gr.null_sink(gr.sizeof_float)
+ self.connect (self.src, c2r,nullsink) #video_sink)
+ elif process_type=='do_tv_sync_corr':
+ frame_size=width*height #int(usrp_rate/25.0)
+ nframes=10# 32
+ search_window=20*nframes
+ debug=False
+ video_alpha=0.3 #0.1
+ corr_alpha=0.3
+ tv_corr=gr.tv_correlator_ff(frame_size,nframes, search_window, video_alpha, corr_alpha,debug) #Note: this block is not yet in cvs
+ shift=gr.add_const_ff(-0.7)
+ self.connect (self.src, self.agc,self.am_demod,tv_corr,self.invert_and_scale, self.set_blacklevel,f2uc,self.dst) #self.agc,
+ else: # process_type=='do_test_image':
+ src_vertical_bars = gr.sig_source_f (usrp_rate, gr.GR_SIN_WAVE, 10.0 *usrp_rate/320, 255,128)
+ self.connect(src_vertical_bars,f2uc,self.dst)
+
+ self._build_gui(vbox, usrp_rate, usrp_rate, usrp_rate)
+
+
+ if abs(options.freq) < 1e6:
+ options.freq *= 1e6
+
+ # set initial values
+ self.set_gain(options.gain)
+ self.set_contrast(self.contrast)
+ self.set_brightness(options.brightness)
+ if not(self.set_freq(options.freq)):
+ self._set_status_msg("Failed to set initial frequency")
+
+
+ def _set_status_msg(self, msg, which=0):
+ self.frame.GetStatusBar().SetStatusText(msg, which)
+
+
+ def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate):
+
+ def _form_set_freq(kv):
+ return self.set_freq(kv['freq'])
+
+
+ if 0:
+ self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP",
+ fft_size=512, sample_rate=usrp_rate)
+ self.connect (self.src, self.src_fft)
+ vbox.Add (self.src_fft.win, 4, wx.EXPAND)
+
+ if 0:
+ post_demod_fft = fftsink.fft_sink_f (self, self.panel, title="Post Demod",
+ fft_size=512, sample_rate=demod_rate,
+ y_per_div=10, ref_level=-40)
+ self.connect (self.am_demod, post_demod_fft)
+ vbox.Add (post_demod_fft.win, 4, wx.EXPAND)
+
+ if 0:
+ post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Filter",
+ fft_size=512, sample_rate=audio_rate,
+ y_per_div=10, ref_level=-40)
+ self.connect (self.set_blacklevel, post_filt)
+ vbox.Add (fft_win4, 4, wx.EXPAND)
+
+
+ # control area form at bottom
+ self.myform = myform = form.form()
+
+ if not (self.u is None):
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+ myform['freq'] = form.float_field(
+ parent=self.panel, sizer=hbox, label="Freq", weight=1,
+ callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+ hbox.Add((5,0), 0)
+ myform['freq_slider'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3,
+ range=(50.25e6, 900.25e6, 0.25e6),
+ callback=self.set_freq)
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+
+ myform['contrast'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Contrast",
+ weight=3, range=(-2.0, 2.0, 0.1),
+ callback=self.set_contrast)
+ hbox.Add((5,0), 1)
+
+ myform['brightness'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Brightness",
+ weight=3, range=(-255.0, 255.0, 1.0),
+ callback=self.set_brightness)
+ hbox.Add((5,0), 0)
+
+ if not (self.u is None):
+ myform['gain'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain",
+ weight=3, range=self.subdev.gain_range(),
+ callback=self.set_gain)
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ try:
+ self.knob = powermate.powermate(self.frame)
+ self.rot = 0
+ powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate)
+ powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button)
+ except:
+ print "FYI: No Powermate or Contour Knob found"
+
+
+ def on_rotate (self, event):
+ self.rot += event.delta
+ if (self.state == "FREQ"):
+ if self.rot >= 3:
+ self.set_freq(self.freq + .1e6)
+ self.rot -= 3
+ elif self.rot <=-3:
+ self.set_freq(self.freq - .1e6)
+ self.rot += 3
+ elif (self.state == "CONTRAST"):
+ step = 0.1
+ if self.rot >= 3:
+ self.set_contrast(self.contrast + step)
+ self.rot -= 3
+ elif self.rot <=-3:
+ self.set_contrast(self.contrast - step)
+ self.rot += 3
+ else:
+ step = 1
+ if self.rot >= 3:
+ self.set_brightness(self.brightness + step)
+ self.rot -= 3
+ elif self.rot <=-3:
+ self.set_brightness(self.brightness - step)
+ self.rot += 3
+
+ def on_button (self, event):
+ if event.value == 0: # button up
+ return
+ self.rot = 0
+ if self.state == "FREQ":
+ self.state = "CONTRAST"
+ elif self.state == "CONTRAST":
+ self.state = "BRIGHTNESS"
+ else:
+ self.state = "FREQ"
+ self.update_status_bar ()
+
+
+ def set_contrast (self, contrast):
+ self.contrast = contrast
+ self.invert_and_scale.set_k(-self.contrast *128.0*255.0/(200.0))
+ self.myform['contrast'].set_value(self.contrast)
+ self.update_status_bar ()
+
+ def set_brightness (self, brightness):
+ self.brightness = brightness
+ self.set_blacklevel.set_k(self.brightness +255.0)
+ self.myform['brightness'].set_value(self.brightness)
+ self.update_status_bar ()
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital down converter.
+ """
+ if not (self.u is None):
+ r = usrp.tune(self.u, 0, self.subdev, target_freq)
+ if r:
+ self.freq = target_freq
+ self.myform['freq'].set_value(target_freq) # update displayed value
+ self.myform['freq_slider'].set_value(target_freq) # update displayed value
+ self.update_status_bar()
+ self._set_status_msg("OK", 0)
+ return True
+
+ self._set_status_msg("Failed", 0)
+ return False
+
+ def set_gain(self, gain):
+ if not (self.u is None):
+ self.gain=gain
+ self.myform['gain'].set_value(gain) # update displayed value
+ self.subdev.set_gain(gain)
+ self.update_status_bar()
+
+ def update_status_bar (self):
+ msg = "Setting:%s Contrast:%r Brightness:%r Gain: %r" % (self.state, self.contrast,self.brightness,self.gain)
+ self._set_status_msg(msg, 1)
+ #self.src_fft.set_baseband_freq(self.freq)
+
+
+
+if __name__ == '__main__':
+ app = stdgui.stdapp (tv_rx_graph, "USRP TV RX black-and-white")
+ app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py b/gnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py
new file mode 100755
index 000000000..e563188b9
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py
@@ -0,0 +1,179 @@
+#!/usr/bin/env python
+
+"""
+Reads from a file and generates PAL TV pictures in black and white
+which can be displayed using ImageMagick or realtime using gr-video-sdl
+(To capture the input file Use usrp_rx_file.py, or use usrp_rx_cfile.py --output-shorts if you have a recent enough usrp_rx_cfile.py)
+Can also use usrp directly as capture source, but then you need a higher decimation factor (64)
+and thus get a lower horizontal resulution.
+There is no synchronisation yet. The sync blocks are in development but not yet in cvs.
+
+"""
+
+from gnuradio import gr, eng_notation
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+
+try:
+ from gnuradio import video_sdl
+except:
+ print "FYI: gr-video-sdl is not installed"
+ print "realtime \"sdl\" video output window will not be available"
+
+
+class my_graph(gr.flow_graph):
+
+ def __init__(self):
+ gr.flow_graph.__init__(self)
+
+ usage="%prog: [options] output_filename. \n Special output_filename \"sdl\" will use video_sink_sdl as realtime output window. " \
+ "You then need to have gr-video-sdl installed. \n" \
+ "Make sure your input capture file containes interleaved shorts not complex floats"
+ parser = OptionParser(option_class=eng_option, usage=usage)
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0),
+ help="select USRP Rx side A or B (default=A)")
+ parser.add_option("-c", "--contrast", type="eng_float", default=1.0,
+ help="set contrast (default is 1.0)")
+ parser.add_option("-b", "--brightness", type="eng_float", default=0.0,
+ help="set brightness (default is 0)")
+ parser.add_option("-d", "--decim", type="int", default=8,
+ help="set fgpa decimation rate to DECIM [default=%default]")
+ parser.add_option("-i", "--in-filename", type="string", default=None,
+ help="Use input file as source. samples must be interleaved shorts \n " +
+ "Use usrp_rx_file.py or usrp_rx_cfile.py --output-shorts. \n"
+ "Special name \"usrp\" results in realtime capturing and processing using usrp. \n" +
+ "You then probably need a decimation factor of 64 or higher.")
+ parser.add_option("-f", "--freq", type="eng_float", default=None,
+ help="set frequency to FREQ.\nNote that the frequency of the video carrier is not at the middle of the TV channel", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=None,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option("-p", "--pal", action="store_true", default=False,
+ help="PAL video format (this is the default)")
+ parser.add_option("-n", "--ntsc", action="store_true", default=False,
+ help="NTSC video format")
+ parser.add_option("-r", "--repeat", action="store_false", default=True,
+ help="repeat in_file in a loop")
+ parser.add_option("-8", "--width-8", action="store_true", default=False,
+ help="Enable 8-bit samples across USB")
+ parser.add_option("-N", "--nframes", type="eng_float", default=None,
+ help="number of frames to collect [default=+inf]")
+ parser.add_option( "--no-hb", action="store_true", default=False,
+ help="don't use halfband filter in usrp")
+ (options, args) = parser.parse_args ()
+ if not (len(args) == 1):
+ parser.print_help()
+ sys.stderr.write('You must specify the output. FILENAME or sdl \n');
+ sys.exit(1)
+
+ filename = args[0]
+
+ if options.in_filename is None:
+ parser.print_help()
+ sys.stderr.write('You must specify the input -i FILENAME or -i usrp\n');
+ raise SystemExit, 1
+
+ if not (filename=="sdl"):
+ options.repeat=False
+
+ if not (options.in_filename=="usrp"):
+ self.filesource = gr.file_source(gr.sizeof_short,options.in_filename,options.repeat) # file is data source, capture with usr_rx_csfile.py
+ self.istoc = gr.interleaved_short_to_complex()
+ self.connect(self.filesource,self.istoc)
+ self.adc_rate=64e6
+ self.src=self.istoc
+ else:
+ if options.freq is None:
+ parser.print_help()
+ sys.stderr.write('You must specify the frequency with -f FREQ\n');
+ raise SystemExit, 1
+ if abs(options.freq) < 1e6:
+ options.freq *= 1e6
+ if options.no_hb or (options.decim<8):
+ self.fpga_filename="std_4rx_0tx.rbf" #contains 4 Rx paths without halfbands and 0 tx paths
+ else:
+ self.fpga_filename="std_2rxhb_2tx.rbf" # contains 2 Rx paths with halfband filters and 2 tx paths (the default)
+
+ # build the graph
+ self.u = usrp.source_c(decim_rate=options.decim,fpga_filename=self.fpga_filename)
+ self.src=self.u
+ if options.width_8:
+ sample_width = 8
+ sample_shift = 8
+ format = self.u.make_format(sample_width, sample_shift)
+ r = self.u.set_format(format)
+ self.adc_rate=self.u.adc_freq()
+ if options.rx_subdev_spec is None:
+ options.rx_subdev_spec = usrp.pick_rx_subdevice(self.u)
+ self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+ # determine the daughterboard subdevice we're using
+ self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+ print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+
+ if options.gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.subdev.gain_range()
+ options.gain = float(g[0]+g[1])/2
+ self.subdev.set_gain(options.gain)
+
+ r = self.u.tune(0, self.subdev, options.freq)
+ if not r:
+ sys.stderr.write('Failed to set frequency\n')
+ raise SystemExit, 1
+
+ input_rate = self.adc_rate / options.decim
+ print "video sample rate %s" % (eng_notation.num_to_str(input_rate))
+
+ self.agc=gr.agc_cc(1e-7,1.0,1.0) #1e-7
+ self.am_demod = gr.complex_to_mag ()
+ self.set_blacklevel=gr.add_const_ff(options.brightness +255.0)
+ self.invert_and_scale = gr.multiply_const_ff (-options.contrast *128.0*255.0/(200.0))
+ self.f2uc=gr.float_to_uchar()
+
+ # sdl window as final sink
+ if not (options.pal or options.ntsc):
+ options.pal=True #set default to PAL
+ if options.pal:
+ lines_per_frame=625.0
+ frames_per_sec=25.0
+ show_width=768
+ elif options.ntsc:
+ lines_per_frame=525.0
+ frames_per_sec=29.97002997
+ show_width=640
+ width=int(input_rate/(lines_per_frame*frames_per_sec))
+ height=int(lines_per_frame)
+
+ if filename=="sdl":
+ #Here comes the tv screen, you have to build and install gr-video-sdl for this (subproject of gnuradio, only in cvs for now)
+ try:
+ video_sink = video_sdl.sink_uc ( frames_per_sec, width, height,0,show_width,height)
+ except:
+ print "gr-video-sdl is not installed"
+ print "realtime \"sdl\" video output window is not available"
+ raise SystemExit, 1
+ self.dst=video_sink
+ else:
+ print "You can use the imagemagick display tool to show the resulting imagesequence"
+ print "use the following line to show the demodulated TV-signal:"
+ print "display -depth 8 -size " +str(width)+ "x" + str(height) + " gray:" +filename
+ print "(Use the spacebar to advance to next frames)"
+ file_sink=gr.file_sink(gr.sizeof_char, filename)
+ self.dst =file_sink
+
+ if options.nframes is None:
+ self.connect(self.src, self.agc)
+ else:
+ self.head = gr.head(gr.sizeof_gr_complex, int(options.nframes*width*height))
+ self.connect(self.src, self.head, self.agc)
+
+ self.connect (self.agc,self.am_demod,self.invert_and_scale, self.set_blacklevel,self.f2uc,self.dst)
+
+
+if __name__ == '__main__':
+ try:
+ my_graph().run()
+ except KeyboardInterrupt:
+ pass
diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv.py
new file mode 100755
index 000000000..202910767
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_wfm_rcv.py
@@ -0,0 +1,269 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import slider, powermate
+from gnuradio.wxgui import stdgui, fftsink, form
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+import wx
+
+def pick_subdevice(u):
+ """
+ The user didn't specify a subdevice on the command line.
+ Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
+
+ @return a subdev_spec
+ """
+ return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
+ usrp_dbid.TV_RX_REV_2,
+ usrp_dbid.BASIC_RX))
+
+
+class wfm_rx_graph (stdgui.gui_flow_graph):
+ def __init__(self,frame,panel,vbox,argv):
+ stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)
+
+ parser=OptionParser(option_class=eng_option)
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+ help="select USRP Rx side A or B (default=A)")
+ parser.add_option("-f", "--freq", type="eng_float", default=100.1e6,
+ help="set frequency to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=40,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option("-V", "--volume", type="eng_float", default=None,
+ help="set volume (default is midpoint)")
+ parser.add_option("-O", "--audio-output", type="string", default="",
+ help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp")
+
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+
+ self.frame = frame
+ self.panel = panel
+
+ self.vol = 0
+ self.state = "FREQ"
+ self.freq = 0
+
+ # build graph
+
+ self.u = usrp.source_c() # usrp is data source
+
+ adc_rate = self.u.adc_rate() # 64 MS/s
+ usrp_decim = 200
+ self.u.set_decim_rate(usrp_decim)
+ usrp_rate = adc_rate / usrp_decim # 320 kS/s
+ chanfilt_decim = 1
+ demod_rate = usrp_rate / chanfilt_decim
+ audio_decimation = 10
+ audio_rate = demod_rate / audio_decimation # 32 kHz
+
+ if options.rx_subdev_spec is None:
+ options.rx_subdev_spec = pick_subdevice(self.u)
+
+ self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+ self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+ print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+
+
+ chan_filt_coeffs = optfir.low_pass (1, # gain
+ usrp_rate, # sampling rate
+ 80e3, # passband cutoff
+ 115e3, # stopband cutoff
+ 0.1, # passband ripple
+ 60) # stopband attenuation
+ #print len(chan_filt_coeffs)
+ chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)
+
+ self.guts = blks.wfm_rcv (self, demod_rate, audio_decimation)
+
+ self.volume_control = gr.multiply_const_ff(self.vol)
+
+ # sound card as final sink
+ audio_sink = audio.sink (int (audio_rate),
+ options.audio_output,
+ False) # ok_to_block
+
+ # now wire it all together
+ self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink)
+
+ self._build_gui(vbox, usrp_rate, demod_rate, audio_rate)
+
+ if options.gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.subdev.gain_range()
+ options.gain = float(g[0]+g[1])/2
+
+ if options.volume is None:
+ g = self.volume_range()
+ options.volume = float(g[0]+g[1])/2
+
+ if abs(options.freq) < 1e6:
+ options.freq *= 1e6
+
+ # set initial values
+
+ self.set_gain(options.gain)
+ self.set_vol(options.volume)
+ if not(self.set_freq(options.freq)):
+ self._set_status_msg("Failed to set initial frequency")
+
+
+ def _set_status_msg(self, msg, which=0):
+ self.frame.GetStatusBar().SetStatusText(msg, which)
+
+
+ def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate):
+
+ def _form_set_freq(kv):
+ return self.set_freq(kv['freq'])
+
+
+ if 1:
+ self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP",
+ fft_size=512, sample_rate=usrp_rate)
+ self.connect (self.u, self.src_fft)
+ vbox.Add (self.src_fft.win, 4, wx.EXPAND)
+
+ if 1:
+ post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Demod",
+ fft_size=1024, sample_rate=usrp_rate,
+ y_per_div=10, ref_level=0)
+ self.connect (self.guts.fm_demod, post_filt_fft)
+ vbox.Add (post_filt_fft.win, 4, wx.EXPAND)
+
+ if 0:
+ post_deemph_fft = fftsink.fft_sink_f (self, self.panel, title="Post Deemph",
+ fft_size=512, sample_rate=audio_rate,
+ y_per_div=10, ref_level=-20)
+ self.connect (self.guts.deemph, post_deemph_fft)
+ vbox.Add (post_deemph_fft.win, 4, wx.EXPAND)
+
+
+ # control area form at bottom
+ self.myform = myform = form.form()
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+ myform['freq'] = form.float_field(
+ parent=self.panel, sizer=hbox, label="Freq", weight=1,
+ callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+ hbox.Add((5,0), 0)
+ myform['freq_slider'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3,
+ range=(87.9e6, 108.1e6, 0.1e6),
+ callback=self.set_freq)
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+
+ myform['volume'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume",
+ weight=3, range=self.volume_range(),
+ callback=self.set_vol)
+ hbox.Add((5,0), 1)
+
+ myform['gain'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain",
+ weight=3, range=self.subdev.gain_range(),
+ callback=self.set_gain)
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ try:
+ self.knob = powermate.powermate(self.frame)
+ self.rot = 0
+ powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate)
+ powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button)
+ except:
+ print "FYI: No Powermate or Contour Knob found"
+
+
+ def on_rotate (self, event):
+ self.rot += event.delta
+ if (self.state == "FREQ"):
+ if self.rot >= 3:
+ self.set_freq(self.freq + .1e6)
+ self.rot -= 3
+ elif self.rot <=-3:
+ self.set_freq(self.freq - .1e6)
+ self.rot += 3
+ else:
+ step = self.volume_range()[2]
+ if self.rot >= 3:
+ self.set_vol(self.vol + step)
+ self.rot -= 3
+ elif self.rot <=-3:
+ self.set_vol(self.vol - step)
+ self.rot += 3
+
+ def on_button (self, event):
+ if event.value == 0: # button up
+ return
+ self.rot = 0
+ if self.state == "FREQ":
+ self.state = "VOL"
+ else:
+ self.state = "FREQ"
+ self.update_status_bar ()
+
+
+ def set_vol (self, vol):
+ g = self.volume_range()
+ self.vol = max(g[0], min(g[1], vol))
+ self.volume_control.set_k(10**(self.vol/10))
+ self.myform['volume'].set_value(self.vol)
+ self.update_status_bar ()
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital down converter.
+ """
+ r = usrp.tune(self.u, 0, self.subdev, target_freq)
+
+ if r:
+ self.freq = target_freq
+ self.myform['freq'].set_value(target_freq) # update displayed value
+ self.myform['freq_slider'].set_value(target_freq) # update displayed value
+ self.update_status_bar()
+ self._set_status_msg("OK", 0)
+ return True
+
+ self._set_status_msg("Failed", 0)
+ return False
+
+ def set_gain(self, gain):
+ self.myform['gain'].set_value(gain) # update displayed value
+ self.subdev.set_gain(gain)
+
+ def update_status_bar (self):
+ msg = "Volume:%r Setting:%s" % (self.vol, self.state)
+ self._set_status_msg(msg, 1)
+ self.src_fft.set_baseband_freq(self.freq)
+
+ def volume_range(self):
+ return (-20.0, 0.0, 0.5)
+
+
+if __name__ == '__main__':
+ app = stdgui.stdapp (wfm_rx_graph, "USRP WFM RX")
+ app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py
new file mode 100755
index 000000000..40e7dd754
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+
+def pick_subdevice(u):
+ """
+ The user didn't specify a subdevice on the command line.
+ Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
+
+ @return a subdev_spec
+ """
+ return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
+ usrp_dbid.TV_RX_REV_2,
+ usrp_dbid.BASIC_RX))
+
+
+class wfm_rx_graph (gr.flow_graph):
+
+ def __init__(self):
+ gr.flow_graph.__init__(self)
+
+ parser=OptionParser(option_class=eng_option)
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+ help="select USRP Rx side A or B (default=A)")
+ parser.add_option("", "--f1", type="eng_float", default=100.7e6,
+ help="set 1st station frequency to FREQ", metavar="FREQ")
+ parser.add_option("", "--f2", type="eng_float", default=102.5e6,
+ help="set 2nd station freq to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=40,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option("-O", "--audio-output", type="string", default="",
+ help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp")
+
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+
+ if abs(options.f1) < 1e6:
+ options.f1 *= 1e6
+
+ if abs(options.f2) < 1e6:
+ options.f2 *= 1e6
+
+ if abs(options.f1 - options.f2) > 5.5e6:
+ print "Sorry, two stations must be within 5.5MHz of each other"
+ raise SystemExit
+
+ f = (options.f1, options.f2)
+
+ self.vol = .1
+ self.state = "FREQ"
+
+ # build graph
+
+ self.u = usrp.source_c(0, nchan=2) # usrp is data source
+
+ adc_rate = self.u.adc_rate() # 64 MS/s
+ usrp_decim = 200
+ self.u.set_decim_rate(usrp_decim)
+ usrp_rate = adc_rate / usrp_decim # 320 kS/s
+ chanfilt_decim = 1
+ demod_rate = usrp_rate / chanfilt_decim
+ audio_decimation = 10
+ audio_rate = demod_rate / audio_decimation # 32 kHz
+
+
+ if options.rx_subdev_spec is None:
+ options.rx_subdev_spec = pick_subdevice(self.u)
+
+ mv = usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)
+ mv |= (mv << 8) & 0xff00 # both DDC inputs setup same way
+ self.u.set_mux(mv)
+ self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+ print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+
+
+ # deinterleave two channels from FPGA
+ di = gr.deinterleave(gr.sizeof_gr_complex)
+
+ # wire up the head of the chain
+ self.connect(self.u, di)
+
+ # sound card as final sink
+ audio_sink = audio.sink(int(audio_rate), options.audio_output)
+
+ # taps for channel filter
+ chan_filt_coeffs = optfir.low_pass (1, # gain
+ usrp_rate, # sampling rate
+ 80e3, # passband cutoff
+ 115e3, # stopband cutoff
+ 0.1, # passband ripple
+ 60) # stopband attenuation
+ #print len(chan_filt_coeffs)
+
+ mid_freq = (f[0] + f[1]) / 2
+ # set front end PLL to middle frequency
+ ok, baseband_freq = self.subdev.set_freq(mid_freq)
+
+ for n in range(2):
+ chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)
+ guts = blks.wfm_rcv (self, demod_rate, audio_decimation)
+ volume_control = gr.multiply_const_ff(self.vol)
+ self.connect((di, n), chan_filt)
+ self.connect(chan_filt, guts, volume_control)
+ self.connect(volume_control, (audio_sink, n))
+ dxc_freq, inverted = usrp.calc_dxc_freq(f[n], baseband_freq,
+ self.u.converter_rate())
+ self.u.set_rx_freq(n, dxc_freq)
+
+
+ if options.gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.subdev.gain_range()
+ options.gain = float(g[0]+g[1])/2
+
+
+ # set initial values
+ self.set_gain(options.gain)
+
+
+ def set_vol (self, vol):
+ self.vol = vol
+ self.volume_control.set_k(self.vol)
+
+
+ def set_gain(self, gain):
+ self.subdev.set_gain(gain)
+
+
+if __name__ == '__main__':
+ fg = wfm_rx_graph()
+ try:
+ fg.run()
+ except KeyboardInterrupt:
+ pass
diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py
new file mode 100755
index 000000000..69f810bba
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py
@@ -0,0 +1,153 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+
+def pick_subdevice(u):
+ """
+ The user didn't specify a subdevice on the command line.
+ Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
+
+ @return a subdev_spec
+ """
+ return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
+ usrp_dbid.TV_RX_REV_2,
+ usrp_dbid.BASIC_RX))
+
+
+class wfm_rx_graph (gr.flow_graph):
+
+ def __init__(self):
+ gr.flow_graph.__init__(self)
+
+ parser=OptionParser(option_class=eng_option)
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+ help="select USRP Rx side A or B (default=A)")
+ parser.add_option("-f", "--freq", type="eng_float", default=100.1e6,
+ help="set frequency to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=None,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option("-O", "--audio-output", type="string", default="",
+ help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp")
+
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+
+ self.vol = .1
+ self.state = "FREQ"
+ self.freq = 0
+
+ # build graph
+
+ self.u = usrp.source_c() # usrp is data source
+
+ adc_rate = self.u.adc_rate() # 64 MS/s
+ usrp_decim = 200
+ self.u.set_decim_rate(usrp_decim)
+ usrp_rate = adc_rate / usrp_decim # 320 kS/s
+ chanfilt_decim = 1
+ demod_rate = usrp_rate / chanfilt_decim
+ audio_decimation = 10
+ audio_rate = demod_rate / audio_decimation # 32 kHz
+
+
+ if options.rx_subdev_spec is None:
+ options.rx_subdev_spec = pick_subdevice(self.u)
+
+ self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+ self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+ print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+
+
+ chan_filt_coeffs = optfir.low_pass (1, # gain
+ usrp_rate, # sampling rate
+ 80e3, # passband cutoff
+ 115e3, # stopband cutoff
+ 0.1, # passband ripple
+ 60) # stopband attenuation
+ #print len(chan_filt_coeffs)
+ chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)
+
+ self.guts = blks.wfm_rcv (self, demod_rate, audio_decimation)
+
+ self.volume_control = gr.multiply_const_ff(self.vol)
+
+ # sound card as final sink
+ audio_sink = audio.sink(int(audio_rate),
+ options.audio_output,
+ False) # ok_to_block
+
+ # now wire it all together
+ self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink)
+
+
+ if options.gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.subdev.gain_range()
+ options.gain = float(g[0]+g[1])/2
+
+ if abs(options.freq) < 1e6:
+ options.freq *= 1e6
+
+ # set initial values
+
+ self.set_gain(options.gain)
+
+ if not(self.set_freq(options.freq)):
+ self._set_status_msg("Failed to set initial frequency")
+
+ def set_vol (self, vol):
+ self.vol = vol
+ self.volume_control.set_k(self.vol)
+ self.update_status_bar ()
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital down converter.
+ """
+ r = self.u.tune(0, self.subdev, target_freq)
+
+ if r:
+ self.freq = target_freq
+ self.update_status_bar()
+ self._set_status_msg("OK", 0)
+ return True
+
+ self._set_status_msg("Failed", 0)
+ return False
+
+ def set_gain(self, gain):
+ self.subdev.set_gain(gain)
+
+ def update_status_bar (self):
+ msg = "Freq: %s Volume:%f Setting:%s" % (
+ eng_notation.num_to_str(self.freq), self.vol, self.state)
+ self._set_status_msg(msg, 1)
+
+ def _set_status_msg(self, msg, which=0):
+ print msg
+
+
+if __name__ == '__main__':
+ fg = wfm_rx_graph()
+ try:
+ fg.run()
+ except KeyboardInterrupt:
+ pass
diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py
new file mode 100755
index 000000000..773076ae5
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py
@@ -0,0 +1,311 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import slider, powermate
+from gnuradio.wxgui import stdgui, fftsink, form, scopesink
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+import wx
+
+def pick_subdevice(u):
+ """
+ The user didn't specify a subdevice on the command line.
+ Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
+
+ @return a subdev_spec
+ """
+ return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
+ usrp_dbid.TV_RX_REV_2,
+ usrp_dbid.BASIC_RX))
+
+class wfm_rx_graph (stdgui.gui_flow_graph):
+ def __init__(self,frame,panel,vbox,argv):
+ stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)
+
+ parser=OptionParser(option_class=eng_option)
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+ help="select USRP Rx side A or B (default=A)")
+ parser.add_option("-f", "--freq", type="eng_float", default=100.1e6,
+ help="set frequency to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=65,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option("-s", "--squelch", type="eng_float", default=0,
+ help="set squelch level (default is 0)")
+ parser.add_option("-V", "--volume", type="eng_float", default=None,
+ help="set volume (default is midpoint)")
+ parser.add_option("-O", "--audio-output", type="string", default="",
+ help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp")
+
+
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+
+ self.frame = frame
+ self.panel = panel
+
+ self.vol = 0
+ self.state = "FREQ"
+ self.freq = 0
+
+ # build graph
+
+ self.u = usrp.source_c() # usrp is data source
+
+ adc_rate = self.u.adc_rate() # 64 MS/s
+ usrp_decim = 200
+ self.u.set_decim_rate(usrp_decim)
+ usrp_rate = adc_rate / usrp_decim # 320 kS/s
+ chanfilt_decim = 1
+ demod_rate = usrp_rate / chanfilt_decim
+ audio_decimation = 10
+ audio_rate = demod_rate / audio_decimation # 32 kHz
+
+ if options.rx_subdev_spec is None:
+ options.rx_subdev_spec = pick_subdevice(self.u)
+
+ self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+ self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+
+
+ chan_filt_coeffs = optfir.low_pass (1, # gain
+ usrp_rate, # sampling rate
+ 80e3, # passband cutoff
+ 115e3, # stopband cutoff
+ 0.1, # passband ripple
+ 60) # stopband attenuation
+ #print len(chan_filt_coeffs)
+ chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)
+
+
+ #self.guts = blks.wfm_rcv (self, demod_rate, audio_decimation)
+ self.guts = blks.wfm_rcv_pll (self, demod_rate, audio_decimation)
+
+ # FIXME rework {add,multiply}_const_* to handle multiple streams
+ self.volume_control_l = gr.multiply_const_ff(self.vol)
+ self.volume_control_r = gr.multiply_const_ff(self.vol)
+
+ # sound card as final sink
+ audio_sink = audio.sink (int (audio_rate),
+ options.audio_output,
+ False) # ok_to_block
+
+ # now wire it all together
+ self.connect (self.u, chan_filt, self.guts)
+ self.connect ((self.guts, 0), self.volume_control_l, (audio_sink, 0))
+ self.connect ((self.guts, 1), self.volume_control_r, (audio_sink, 1))
+ self.guts.stereo_carrier_pll_recovery.squelch_enable(True);
+
+ self._build_gui(vbox, usrp_rate, demod_rate, audio_rate)
+
+ if options.gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.subdev.gain_range()
+ options.gain = float(g[0]+g[1])/2
+
+ if options.volume is None:
+ g = self.volume_range()
+ options.volume = float(g[0]+g[1])/2
+
+ if abs(options.freq) < 1e6:
+ options.freq *= 1e6
+
+ # set initial values
+
+ self.set_gain(options.gain)
+ self.set_vol(options.volume)
+ self.guts.stereo_carrier_pll_recovery.set_lock_threshold(options.squelch);
+ if not(self.set_freq(options.freq)):
+ self._set_status_msg("Failed to set initial frequency")
+
+
+ def _set_status_msg(self, msg, which=0):
+ self.frame.GetStatusBar().SetStatusText(msg, which)
+
+
+ def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate):
+
+ def _form_set_freq(kv):
+ return self.set_freq(kv['freq'])
+
+
+ if 1:
+ self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP",
+ fft_size=512, sample_rate=usrp_rate)
+ self.connect (self.u, self.src_fft)
+ vbox.Add (self.src_fft.win, 4, wx.EXPAND)
+
+ if 1:
+ post_fm_demod_fft = fftsink.fft_sink_f (self, self.panel, title="Post FM Demod",
+ fft_size=512, sample_rate=demod_rate,
+ y_per_div=10, ref_level=0)
+ self.connect (self.guts.fm_demod, post_fm_demod_fft)
+ vbox.Add (post_fm_demod_fft.win, 4, wx.EXPAND)
+
+ if 0:
+ post_stereo_carrier_generator_fft = fftsink.fft_sink_c (self, self.panel, title="Post Stereo_carrier_generator",
+ fft_size=512, sample_rate=audio_rate,
+ y_per_div=10, ref_level=0)
+ self.connect (self.guts.stereo_carrier_generator, post_stereo_carrier_generator_fft)
+ vbox.Add (post_stereo_carrier_generator_fft.win, 4, wx.EXPAND)
+
+ if 0:
+ post_deemphasis_left = fftsink.fft_sink_f (self, self.panel, title="Post_Deemphasis_Left",
+ fft_size=512, sample_rate=audio_rate,
+ y_per_div=10, ref_level=0)
+ self.connect (self.guts.deemph_Left, post_deemphasis_left)
+ vbox.Add (post_deemphasis_left.win, 4, wx.EXPAND)
+
+ if 0:
+ post_deemphasis_right = fftsink.fft_sink_f (self, self.panel, title="Post_Deemphasis_Right",
+ fft_size=512, sample_rate=audio_rate,
+ y_per_div=10, ref_level=-20)
+ self.connect (self.guts.deemph_Left, post_deemphasis_right)
+ vbox.Add (post_deemphasis_right.win, 4, wx.EXPAND)
+
+
+ if 0:
+ LmR_fft = fftsink.fft_sink_f (self, self.panel, title="LmR",
+ fft_size=512, sample_rate=audio_rate,
+ y_per_div=10, ref_level=-20)
+ self.connect (self.guts.LmR_real,LmR_fft)
+ vbox.Add (LmR_fft.win, 4, wx.EXPAND)
+
+ if 0:
+ self.scope = scopesink.scope_sink_f(self, self.panel, sample_rate=demod_rate)
+ self.connect (self.guts.fm_demod_a,self.scope)
+ vbox.Add (self.scope.win,4,wx.EXPAND)
+
+ # control area form at bottom
+ self.myform = myform = form.form()
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+ myform['freq'] = form.float_field(
+ parent=self.panel, sizer=hbox, label="Freq", weight=1,
+ callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+ hbox.Add((5,0), 0)
+ myform['freq_slider'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3,
+ range=(87.9e6, 108.1e6, 0.1e6),
+ callback=self.set_freq)
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+
+ myform['volume'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume",
+ weight=3, range=self.volume_range(),
+ callback=self.set_vol)
+ hbox.Add((5,0), 1)
+
+ myform['gain'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain",
+ weight=3, range=self.subdev.gain_range(),
+ callback=self.set_gain)
+ hbox.Add((5,0), 0)
+
+ myform['sqlch_thrsh'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Stereo Squelch Threshold",
+ weight=3, range=(0.0,1.0,0.01),
+ callback=self.guts.stereo_carrier_pll_recovery.set_lock_threshold)
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ try:
+ self.knob = powermate.powermate(self.frame)
+ self.rot = 0
+ powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate)
+ powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button)
+ except:
+ print "FYI: No Powermate or Contour Knob found"
+
+
+ def on_rotate (self, event):
+ self.rot += event.delta
+ if (self.state == "FREQ"):
+ if self.rot >= 3:
+ self.set_freq(self.freq + .1e6)
+ self.rot -= 3
+ elif self.rot <=-3:
+ self.set_freq(self.freq - .1e6)
+ self.rot += 3
+ else:
+ step = self.volume_range()[2]
+ if self.rot >= 3:
+ self.set_vol(self.vol + step)
+ self.rot -= 3
+ elif self.rot <=-3:
+ self.set_vol(self.vol - step)
+ self.rot += 3
+
+ def on_button (self, event):
+ if event.value == 0: # button up
+ return
+ self.rot = 0
+ if self.state == "FREQ":
+ self.state = "VOL"
+ else:
+ self.state = "FREQ"
+ self.update_status_bar ()
+
+
+ def set_vol (self, vol):
+ g = self.volume_range()
+ self.vol = max(g[0], min(g[1], vol))
+ self.volume_control_l.set_k(10**(self.vol/10))
+ self.volume_control_r.set_k(10**(self.vol/10))
+ self.myform['volume'].set_value(self.vol)
+ self.update_status_bar ()
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital down converter.
+ """
+ r = usrp.tune(self.u, 0, self.subdev, target_freq)
+
+ if r:
+ self.freq = target_freq
+ self.myform['freq'].set_value(target_freq) # update displayed value
+ self.myform['freq_slider'].set_value(target_freq) # update displayed value
+ self.update_status_bar()
+ self._set_status_msg("OK", 0)
+ return True
+
+ self._set_status_msg("Failed", 0)
+ return False
+
+ def set_gain(self, gain):
+ self.myform['gain'].set_value(gain) # update displayed value
+ self.subdev.set_gain(gain)
+
+ def update_status_bar (self):
+ msg = "Volume:%r Setting:%s" % (self.vol, self.state)
+ self._set_status_msg(msg, 1)
+ self.src_fft.set_baseband_freq(self.freq)
+
+ def volume_range(self):
+ return (-20.0, 0.0, 0.5)
+
+
+if __name__ == '__main__':
+ app = stdgui.stdapp (wfm_rx_graph, "USRP WFM RX")
+ app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/usrp_wxapt_rcv.py b/gnuradio-examples/python/usrp/usrp_wxapt_rcv.py
new file mode 100755
index 000000000..7c04c988a
--- /dev/null
+++ b/gnuradio-examples/python/usrp/usrp_wxapt_rcv.py
@@ -0,0 +1,267 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import slider, powermate
+from gnuradio.wxgui import stdgui, fftsink, form
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+import wx
+
+def pick_subdevice(u):
+ """
+ The user didn't specify a subdevice on the command line.
+ Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
+
+ @return a subdev_spec
+ """
+ return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
+ usrp_dbid.TV_RX_REV_2,
+ usrp_dbid.BASIC_RX))
+
+
+class wxapt_rx_graph (stdgui.gui_flow_graph):
+ def __init__(self,frame,panel,vbox,argv):
+ stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)
+
+ parser=OptionParser(option_class=eng_option)
+ parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+ help="select USRP Rx side A or B (default=A)")
+ parser.add_option("-f", "--freq", type="eng_float", default=137.5e6,
+ help="set frequency to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=None,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option("-V", "--volume", type="eng_float", default=None,
+ help="set volume (default is midpoint)")
+ parser.add_option("-O", "--audio-output", type="string", default="",
+ help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp")
+
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+
+ self.frame = frame
+ self.panel = panel
+
+ self.vol = 0
+ self.state = "FREQ"
+ self.freq = 0
+
+ # build graph
+
+ self.u = usrp.source_c() # usrp is data source
+
+ adc_rate = self.u.adc_rate() # 64 MS/s
+ usrp_decim = 200
+ self.u.set_decim_rate(usrp_decim)
+ usrp_rate = adc_rate / usrp_decim # 320 kS/s
+ chanfilt_decim = 4
+ demod_rate = usrp_rate / chanfilt_decim
+ audio_decimation = 10
+ audio_rate = demod_rate / audio_decimation # 32 kHz
+
+ if options.rx_subdev_spec is None:
+ options.rx_subdev_spec = pick_subdevice(self.u)
+
+ self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+ self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+ print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+
+
+ chan_filt_coeffs = optfir.low_pass (1, # gain
+ usrp_rate, # sampling rate
+ 40e3, # passband cutoff
+ 60e3, # stopband cutoff
+ 0.1, # passband ripple
+ 60) # stopband attenuation
+ #print len(chan_filt_coeffs)
+ chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)
+
+ self.guts = blks.wfm_rcv (self, demod_rate, audio_decimation)
+
+ self.volume_control = gr.multiply_const_ff(self.vol)
+
+ # sound card as final sink
+ audio_sink = audio.sink (int (audio_rate), options.audio_output)
+
+ # now wire it all together
+ self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink)
+
+ self._build_gui(vbox, usrp_rate, demod_rate, audio_rate)
+
+ if options.gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.subdev.gain_range()
+ options.gain = float(g[0]+g[1])/2
+
+ if options.volume is None:
+ g = self.volume_range()
+ options.volume = float(g[0]+g[1])/2
+
+ if abs(options.freq) < 1e6:
+ options.freq *= 1e6
+
+ # set initial values
+
+ self.set_gain(options.gain)
+ self.set_vol(options.volume)
+ if not(self.set_freq(options.freq)):
+ self._set_status_msg("Failed to set initial frequency")
+
+
+ def _set_status_msg(self, msg, which=0):
+ self.frame.GetStatusBar().SetStatusText(msg, which)
+
+
+ def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate):
+
+ def _form_set_freq(kv):
+ return self.set_freq(kv['freq'])
+
+
+ if 1:
+ self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP",
+ fft_size=512, sample_rate=usrp_rate)
+ self.connect (self.u, self.src_fft)
+ vbox.Add (self.src_fft.win, 4, wx.EXPAND)
+
+ if 1:
+ post_deemph_fft = fftsink.fft_sink_f (self, self.panel, title="Post Deemph",
+ fft_size=512, sample_rate=demod_rate,
+ y_per_div=10, ref_level=-20)
+ self.connect (self.guts.deemph, post_deemph_fft)
+ vbox.Add (post_deemph_fft.win, 4, wx.EXPAND)
+
+ if 1:
+ post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Filter",
+ fft_size=512, sample_rate=audio_rate,
+ y_per_div=10, ref_level=0)
+ self.connect (self.guts.audio_filter, post_filt_fft)
+ vbox.Add (post_filt_fft.win, 4, wx.EXPAND)
+
+
+ # control area form at bottom
+ self.myform = myform = form.form()
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+ myform['freq'] = form.float_field(
+ parent=self.panel, sizer=hbox, label="Freq", weight=1,
+ callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+ hbox.Add((5,0), 0)
+ myform['freq_slider'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3,
+ range=(137.0e6, 138.0e6, 0.0005e6),
+ callback=self.set_freq)
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0)
+
+ myform['volume'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume",
+ weight=3, range=self.volume_range(),
+ callback=self.set_vol)
+ hbox.Add((5,0), 1)
+
+ myform['gain'] = \
+ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain",
+ weight=3, range=self.subdev.gain_range(),
+ callback=self.set_gain)
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ try:
+ self.knob = powermate.powermate(self.frame)
+ self.rot = 0
+ powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate)
+ powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button)
+ except:
+ print "FYI: No Powermate or Contour Knob found"
+
+
+ def on_rotate (self, event):
+ self.rot += event.delta
+ if (self.state == "FREQ"):
+ if self.rot >= 3:
+ self.set_freq(self.freq + .1e6)
+ self.rot -= 3
+ elif self.rot <=-3:
+ self.set_freq(self.freq - .1e6)
+ self.rot += 3
+ else:
+ step = self.volume_range()[2]
+ if self.rot >= 3:
+ self.set_vol(self.vol + step)
+ self.rot -= 3
+ elif self.rot <=-3:
+ self.set_vol(self.vol - step)
+ self.rot += 3
+
+ def on_button (self, event):
+ if event.value == 0: # button up
+ return
+ self.rot = 0
+ if self.state == "FREQ":
+ self.state = "VOL"
+ else:
+ self.state = "FREQ"
+ self.update_status_bar ()
+
+
+ def set_vol (self, vol):
+ g = self.volume_range()
+ self.vol = max(g[0], min(g[1], vol))
+ self.volume_control.set_k(10**(self.vol/10))
+ self.myform['volume'].set_value(self.vol)
+ self.update_status_bar ()
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital down converter.
+ """
+ r = usrp.tune(self.u, 0, self.subdev, target_freq)
+
+ if r:
+ self.freq = target_freq
+ self.myform['freq'].set_value(target_freq) # update displayed value
+ self.myform['freq_slider'].set_value(target_freq) # update displayed value
+ self.update_status_bar()
+ self._set_status_msg("OK", 0)
+ return True
+
+ self._set_status_msg("Failed", 0)
+ return False
+
+ def set_gain(self, gain):
+ self.myform['gain'].set_value(gain) # update displayed value
+ self.subdev.set_gain(gain)
+
+ def update_status_bar (self):
+ msg = "Volume:%r Setting:%s" % (self.vol, self.state)
+ self._set_status_msg(msg, 1)
+ self.src_fft.set_baseband_freq(self.freq)
+
+ def volume_range(self):
+ return (-20.0, 0.0, 0.5)
+
+
+if __name__ == '__main__':
+ app = stdgui.stdapp (wxapt_rx_graph, "USRP WXAPT RX")
+ app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/wfm_rcv_file.py b/gnuradio-examples/python/usrp/wfm_rcv_file.py
new file mode 100755
index 000000000..2c8d4f760
--- /dev/null
+++ b/gnuradio-examples/python/usrp/wfm_rcv_file.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, eng_notation
+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 (input_filename, repeat):
+ adc_rate = 64e6 # USRP A/D sampling rate
+ decim = 250 # FPGA decimated by this amount
+
+ quad_rate = adc_rate / decim # 256 kHz (the sample rate of the file)
+ audio_decimation = 8
+ audio_rate = quad_rate / audio_decimation # 32 kHz
+
+ fg = gr.flow_graph ()
+
+ # usrp is data source
+ # src = usrp.source_c (0, decim)
+ # src.set_rx_freq (0, -IF_freq)
+
+ src = gr.file_source (gr.sizeof_gr_complex, input_filename, repeat)
+
+ (head, tail) = 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, head)
+ fg.connect (tail, (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 downconverteed 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)
+
+ TAU = 75e-6 # 75us in US, 50us in EUR
+ fftaps = [ 1 - math.exp(-1/TAU/quad_rate), 0]
+ fbtaps= [ 0 , math.exp(-1/TAU/quad_rate) ]
+ deemph = gr.iir_filter_ffd(fftaps,fbtaps)
+
+ # input: float; output: float
+ audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
+
+ fg.connect (fm_demod, deemph)
+ fg.connect (deemph, audio_filter)
+ return ((fm_demod, 0), (audio_filter, 0))
+
+
+def main ():
+ usage = "usage: %prog [options] filename"
+ parser = OptionParser (option_class=eng_option, usage=usage)
+ parser.add_option ("-r", "--repeat", action="store_true", default=False)
+ # parser.add_option (... your stuff here...)
+ (options, args) = parser.parse_args ()
+
+ if len (args) != 1:
+ parser.print_help ()
+ sys.exit (1)
+
+ fg = build_graph (args[0], options.repeat)
+
+ fg.start () # fork thread(s) and return
+ raw_input ('Press Enter to quit: ')
+ fg.stop ()
+
+if __name__ == '__main__':
+ main ()
+
+