Merge branch 'grc' of http://gnuradio.org/git/jblum into master
authorJohnathan Corgan <jcorgan@corganenterprises.com>
Thu, 10 Sep 2009 00:38:27 +0000 (17:38 -0700)
committerJohnathan Corgan <jcorgan@corganenterprises.com>
Thu, 10 Sep 2009 00:38:27 +0000 (17:38 -0700)
* 'grc' of http://gnuradio.org/git/jblum:
  use show signal to perform initial gui update
  Fixed the usrp and usrp2 probe scripts to work with the new gui param api.
  propsdialog tweaks
  more code cleanup for properties dialog
  Rework the params/properties dialog and param gui class:
  renamed params dialog to props dialog
  remove unused imports, copyright date update, tweak
  Created recursive create labels and shapes method for gui element.
  replaced dict[rot] storage of areas and lines with a single list for the current rotation
  standardized the Element inheritance __init__ usage in gui
  better error msg for empty statements
  Implement a recursive validation api in the base Element class.

23 files changed:
gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc
gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.cc
gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.cc
gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.cc
gnuradio-core/src/python/gnuradio/Makefile.am
gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am
gnuradio-core/src/python/gnuradio/blks2impl/generic_usrp.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/usrp_options.py [new file with mode: 0644]
gnuradio-examples/python/digital/Makefile.am
gnuradio-examples/python/digital/benchmark_qt_rx.py
gnuradio-examples/python/digital/generic_usrp.py [deleted file]
gnuradio-examples/python/digital/usrp_options.py [deleted file]
gnuradio-examples/python/digital/usrp_receive_path.py
gnuradio-examples/python/digital/usrp_transmit_path.py
gr-utils/src/python/Makefile.am
gr-utils/src/python/qr_fft.py [deleted file]
gr-utils/src/python/usrp2_siggen.py [deleted file]
gr-utils/src/python/usrp2_siggen_gui.py [deleted file]
gr-utils/src/python/usrp_siggen.py
gr-utils/src/python/usrp_siggen_gui.py [new file with mode: 0755]
gr-wxgui/src/python/forms/converters.py
gr-wxgui/src/python/forms/forms.py
gruel/src/lib/.gitignore

index bfc4c04675904dac22e59004e8dfe07319438b96..8971d3d39bb5001598559ddee61a6b039c208894 100644 (file)
@@ -28,6 +28,7 @@
 #include <gr_fir_ccf.h>
 #include <gr_fir_util.h>
 #include <gr_io_signature.h>
+#include <cstdio>
 
 gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate, 
                                                             const std::vector<float> &taps,
index 7be611e236049bd309878313197df03afdc40a4f..a7e8de62ad6a65e7bb1e8914e748c72ecd73a2c6 100644 (file)
@@ -29,6 +29,7 @@
 #include <gr_fir_util.h>
 #include <gri_fft.h>
 #include <gr_io_signature.h>
+#include <cstdio>
 
 gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans, 
                                                         const std::vector<float> &taps)
index b334f58781a78b1e0c4c7678815ac158ef07a596..e05e18ff2e0f04c38bd3ce6c152402e6876806d5 100644 (file)
@@ -30,6 +30,7 @@
 #include <gri_fft.h>
 #include <gr_io_signature.h>
 #include <gr_expj.h>
+#include <cstdio>
 
 gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim, 
                                                     const std::vector<float> &taps,
index d5eba885ca98df622c7013bbabe6db74ba4ebbdc..6a9598f344584b51ccb350d96ad5ead2a63143df 100644 (file)
@@ -28,6 +28,7 @@
 #include <gr_fir_ccf.h>
 #include <gr_fir_util.h>
 #include <gr_io_signature.h>
+#include <cstdio>
 
 gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp, 
                                                           const std::vector<float> &taps)
index ed36bbae7c479e2d8c2cc8c959a2b8ca2a3b3943..dcc0017b3c16660fd7b238a2a106e76720d2b4ee 100644 (file)
@@ -34,5 +34,6 @@ grpython_PYTHON =                     \
        packet_utils.py                 \
        gr_unittest.py                  \
        optfir.py                       \
+       usrp_options.py         \
        window.py
 endif
index 17be09cc73b35ed9239c97700db5e3b463823f5c..f0825b15135fb7cfe19c508578c9466ec2c106c4 100644 (file)
@@ -36,6 +36,7 @@ grblkspython_PYTHON =         \
        filterbank.py           \
        fm_demod.py             \
        fm_emph.py              \
+       generic_usrp.py \
        gmsk.py                 \
        cpm.py                  \
        logpwrfft.py            \
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/generic_usrp.py b/gnuradio-core/src/python/gnuradio/blks2impl/generic_usrp.py
new file mode 100644 (file)
index 0000000..5abbaf9
--- /dev/null
@@ -0,0 +1,244 @@
+#
+# Copyright 2009 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 3, 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., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+USRP1_TYPE = 'usrp1'
+USRP2_TYPE = 'usrp2'
+DUMMY_TYPE = 'dummy'
+#usrp2 rates common for decim and interp
+_USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4)
+#dummy common rates
+_DUMMY_XRATES = range(4, 512, 2)
+_DUMMY_CONVERTER_RATE = 100e6
+#dummy freq result
+class _dummy_freq_result(object):
+    def __init__(self, target_freq):
+        self.baseband_freq = target_freq
+        self.dxc_freq = 0
+        self.residual_freq = 0
+from gnuradio import gr
+
+########################################################################
+# generic usrp common stuff
+########################################################################
+class _generic_usrp_base(object):
+
+    def __init__(self, which=0, subdev_spec=None, interface="", mac_addr="",
+        fusb_block_size=0, fusb_nblocks=0, usrpx=None, lo_offset=None, gain=None):
+        self._lo_offset = lo_offset
+        #usrp options
+        self._which = which
+        self._subdev_spec = subdev_spec
+        #usrp2 options
+        self._interface = interface
+        self._mac_addr = mac_addr
+        #fusb options
+        self._fusb_block_size = fusb_block_size
+        self._fusb_nblocks = fusb_nblocks
+        #pick which usrp model
+        if usrpx == '0': self._setup_usrpx(DUMMY_TYPE)
+        elif usrpx == '1' or self._subdev_spec: self._setup_usrpx(USRP1_TYPE)
+        elif usrpx == '2' or self._mac_addr: self._setup_usrpx(USRP2_TYPE)
+        else: #automatic
+            try: self._setup_usrpx(USRP2_TYPE)
+            except:
+                try: self._setup_usrpx(USRP1_TYPE)
+                except: raise Exception, 'Failed to automatically setup a usrp device.'
+        #post usrp setup
+        if self._lo_offset is not None:
+            self.set_lo_offset(self._lo_offset)
+        self.set_gain(gain)
+        self.set_auto_tr(True)
+
+    def _setup_usrpx(self, type):
+        """
+        Call the appropriate setup method.
+        @param type the usrp type constant
+        """
+        self._type = type
+        if self._type == USRP1_TYPE: self._setup_usrp1()
+        elif self._type == USRP2_TYPE: self._setup_usrp2()
+        elif self._type == DUMMY_TYPE: self._setup_dummy()
+
+    def __str__(self):
+        if self._type == USRP1_TYPE: return self._subdev.side_and_name()
+        elif self._type == USRP2_TYPE:
+            return 'Interface: %s    MAC Address: %s    D-Board ID: 0x%.2x'%(
+                self._u.interface_name(), self._u.mac_addr(), self._u.daughterboard_id())
+        elif self._type == DUMMY_TYPE: return 'Dummy USRP Device'
+
+    def gain(self): return self._gain
+
+    def set_gain(self, gain=None):
+        #automatic gain calculation
+        r = self.gain_range()
+        if gain is None: gain = (r[0] + r[1])/2 # set gain to midpoint
+        #set gain for usrp
+        self._gain = gain
+        if self._type == USRP1_TYPE: return self._subdev.set_gain(gain)
+        elif self._type == USRP2_TYPE: return self._u.set_gain(gain)
+        elif self._type == DUMMY_TYPE: return True
+
+    def gain_range(self):
+        if self._type == USRP1_TYPE: return self._subdev.gain_range()
+        elif self._type == USRP2_TYPE: return self._u.gain_range()
+        elif self._type == DUMMY_TYPE: return (0, 0, 0)
+
+    def set_center_freq(self, target_freq):
+        if self._type == USRP1_TYPE:
+            return self._u.tune(self._dxc, self._subdev, target_freq)
+        elif self._type == USRP2_TYPE:
+            return self._u.set_center_freq(target_freq)
+        elif self._type == DUMMY_TYPE: return _dummy_freq_result(target_freq)
+
+    def freq_range(self):
+        if self._type == USRP1_TYPE: return self._subdev.freq_range()
+        elif self._type == USRP2_TYPE: return self._u.freq_range()
+        elif self._type == DUMMY_TYPE: return (-10e9, 10e9, 100e3)
+
+    def set_lo_offset(self, lo_offset):
+        if self._type == USRP1_TYPE: return self._subdev.set_lo_offset(lo_offset)
+        elif self._type == USRP2_TYPE: return self._u.set_lo_offset(lo_offset)
+        elif self._type == DUMMY_TYPE: return True
+
+    def set_auto_tr(self, enable):
+        if self._type == USRP1_TYPE: return self._subdev.set_auto_tr(enable)
+
+    def __del__(self):
+        try: # Avoid weak reference error
+            del self._u
+            del self._subdev
+        except: pass
+
+########################################################################
+# generic usrp source
+########################################################################
+class generic_usrp_source_c(_generic_usrp_base, gr.hier_block2):
+    """
+    Create a generic usrp source that represents usrp and usrp2.
+    Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
+    Provide generic access methods so the API looks the same for both.
+    """
+
+    def __init__(self, **kwargs):
+        gr.hier_block2.__init__(self, "generic_usrp_source",
+            gr.io_signature(0, 0, 0), # Input signature
+            gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+        _generic_usrp_base.__init__(self, **kwargs)
+        self.connect(self._u, self)
+
+    ####################################################################
+    # generic access methods
+    ####################################################################
+    def set_decim(self, decim):
+        if decim not in self.get_decim_rates(): return False
+        if self._type == USRP1_TYPE: return self._u.set_decim_rate(decim)
+        elif self._type == USRP2_TYPE: return self._u.set_decim(decim)
+        elif self._type == DUMMY_TYPE: return True
+
+    def get_decim_rates(self):
+        if self._type == USRP1_TYPE: return range(8, 256+1, 2) #default firmware w/ hb filters
+        if self._type == USRP2_TYPE: return _USRP2_RATES
+        elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
+
+    def adc_rate(self):
+        if self._type == USRP1_TYPE: return self._u.adc_rate()
+        if self._type == USRP2_TYPE: return self._u.adc_rate()
+        elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
+
+    ####################################################################
+    # setup usrp methods
+    ####################################################################
+    def _setup_usrp1(self):
+        from gnuradio import usrp
+        self._u = usrp.source_c (self._which,
+                                fusb_block_size=self._fusb_block_size,
+                                fusb_nblocks=self._fusb_nblocks)
+        # determine the daughterboard subdevice we're using
+        if self._subdev_spec is None:
+            self._subdev_spec = usrp.pick_rx_subdevice(self._u)
+        self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
+        self._u.set_mux(usrp.determine_rx_mux_value(self._u, self._subdev_spec))
+        self._dxc = 0
+
+    def _setup_usrp2(self):
+        from gnuradio import usrp2
+        self._u = usrp2.source_32fc(self._interface, self._mac_addr)
+
+    def _setup_dummy(self): self._u = gr.null_source(gr.sizeof_gr_complex)
+
+########################################################################
+# generic usrp sink
+########################################################################
+class generic_usrp_sink_c(_generic_usrp_base, gr.hier_block2):
+    """
+    Create a generic usrp sink that represents usrp and usrp2.
+    Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
+    Provide generic access methods so the API looks the same for both.
+    """
+
+    def __init__(self, **kwargs):
+        gr.hier_block2.__init__(self, "generic_usrp_sink",
+            gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+            gr.io_signature(0, 0, 0)) # Output signature
+        _generic_usrp_base.__init__(self, **kwargs)
+        if self._type == USRP1_TYPE: #scale 0.0 to 1.0 input for usrp1
+            self.connect(self, gr.multiply_const_cc((2**15)-1), self._u)
+        else: self.connect(self, self._u)
+
+    ####################################################################
+    # generic access methods
+    ####################################################################
+    def set_interp(self, interp):
+        if interp not in self.get_interp_rates(): return False
+        if self._type == USRP1_TYPE: return self._u.set_interp_rate(interp)
+        elif self._type == USRP2_TYPE: return self._u.set_interp(interp)
+        elif self._type == DUMMY_TYPE: return True
+
+    def get_interp_rates(self):
+        if self._type == USRP1_TYPE: return range(16, 512+1, 4)
+        if self._type == USRP2_TYPE: return _USRP2_RATES
+        elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
+
+    def dac_rate(self):
+        if self._type == USRP1_TYPE: return self._u.dac_rate()
+        if self._type == USRP2_TYPE: return self._u.dac_rate()
+        elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
+
+    ####################################################################
+    # setup usrp methods
+    ####################################################################
+    def _setup_usrp1(self):
+        from gnuradio import usrp
+        self._u = usrp.sink_c (self._which,
+                                fusb_block_size=self._fusb_block_size,
+                                fusb_nblocks=self._fusb_nblocks)
+        # determine the daughterboard subdevice we're using
+        if self._subdev_spec is None:
+            self._subdev_spec = usrp.pick_tx_subdevice(self._u)
+        self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
+        self._u.set_mux(usrp.determine_tx_mux_value(self._u, self._subdev_spec))
+        self._dxc = self._subdev.which()
+
+    def _setup_usrp2(self):
+        from gnuradio import usrp2
+        self._u = usrp2.sink_32fc(self._interface, self._mac_addr)
+
+    def _setup_dummy(self): self._u = gr.null_sink(gr.sizeof_gr_complex)
diff --git a/gnuradio-core/src/python/gnuradio/usrp_options.py b/gnuradio-core/src/python/gnuradio/usrp_options.py
new file mode 100644 (file)
index 0000000..86dba2f
--- /dev/null
@@ -0,0 +1,123 @@
+#
+# Copyright 2009 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 3, 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., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+_parser_to_groups_dict = dict()
+class _parser_groups(object):
+    def __init__(self, parser):
+        self.usrpx_grp = parser.add_option_group("General USRP Options")
+        self.usrp1_grp = parser.add_option_group("USRP1 Specific Options")
+        self.usrp1exp_grp = parser.add_option_group("USRP1 Expert Options")
+        self.usrp2_grp = parser.add_option_group("USRP2 Specific Options")
+
+from gnuradio import blks2
+
+def _add_options(parser):
+    """
+    Add options to manually choose between usrp or usrp2.
+    Add options for usb. Add options common to source and sink.
+    @param parser: instance of OptionParser
+    @return the parser group
+    """
+    #cache groups so they dont get added twice on tranceiver apps
+    if not _parser_to_groups_dict.has_key(parser): _parser_to_groups_dict[parser] = _parser_groups(parser)
+    pg = _parser_to_groups_dict[parser]
+    #pick usrp or usrp2
+    pg.usrpx_grp.add_option("-u", "--usrpx", type="string", default=None,
+                      help="specify which usrp model: 1 for USRP, 2 for USRP2 [default=auto]")
+    #fast usb options
+    pg.usrp1exp_grp.add_option("-B", "--fusb-block-size", type="int", default=0,
+                      help="specify fast usb block size [default=%default]")
+    pg.usrp1exp_grp.add_option("-N", "--fusb-nblocks", type="int", default=0,
+                      help="specify number of fast usb blocks [default=%default]")
+    #lo offset
+    pg.usrpx_grp.add_option("--lo-offset", type="eng_float", default=None,
+                      help="set LO Offset in Hz [default=automatic].")
+    #usrp options
+    pg.usrp1_grp.add_option("-w", "--which", type="int", default=0,
+                      help="select USRP board [default=%default]")
+    #usrp2 options
+    pg.usrp2_grp.add_option("-e", "--interface", type="string", default="eth0",
+                      help="Use USRP2 at specified Ethernet interface [default=%default]")
+    pg.usrp2_grp.add_option("-a", "--mac-addr", type="string", default="",
+                      help="Use USRP2 at specified MAC address [default=None]")
+    return pg
+
+def add_rx_options(parser):
+    """
+    Add receive specific usrp options.
+    @param parser: instance of OptionParser
+    """
+    pg = _add_options(parser)
+    pg.usrp1_grp.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Rx side A or B")
+    pg.usrpx_grp.add_option("--rx-gain", type="eng_float", default=None, metavar="GAIN",
+                      help="set receiver gain in dB [default=midpoint].  See also --show-rx-gain-range")
+    pg.usrpx_grp.add_option("--show-rx-gain-range", action="store_true", default=False, 
+                      help="print min and max Rx gain available on selected daughterboard")
+    pg.usrpx_grp.add_option("-d", "--decim", type="intx", default=None,
+                      help="set fpga decimation rate to DECIM [default=%default]")
+
+def create_usrp_source(options):
+    u = blks2.generic_usrp_source_c(
+        usrpx=options.usrpx,
+        which=options.which,
+        subdev_spec=options.rx_subdev_spec,
+        interface=options.interface,
+        mac_addr=options.mac_addr,
+        fusb_block_size=options.fusb_block_size,
+        fusb_nblocks=options.fusb_nblocks,
+        lo_offset=options.lo_offset,
+        gain=options.rx_gain,
+    )
+    if options.show_rx_gain_range:
+        print "Rx Gain Range: minimum = %g, maximum = %g, step size = %g"%tuple(u.gain_range())
+    return u
+
+def add_tx_options(parser):
+    """
+    Add transmit specific usrp options.
+    @param parser: instance of OptionParser
+    """
+    pg = _add_options(parser)
+    pg.usrp1_grp.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Rx side A or B")
+    pg.usrpx_grp.add_option("--tx-gain", type="eng_float", default=None, metavar="GAIN",
+                      help="set transmitter gain in dB [default=midpoint].  See also --show-tx-gain-range")
+    pg.usrpx_grp.add_option("--show-tx-gain-range", action="store_true", default=False, 
+                      help="print min and max Tx gain available on selected daughterboard")
+    pg.usrpx_grp.add_option("-i", "--interp", type="intx", default=None,
+                      help="set fpga interpolation rate to INTERP [default=%default]")
+
+def create_usrp_sink(options):
+    u = blks2.generic_usrp_sink_c(
+        usrpx=options.usrpx,
+        which=options.which,
+        subdev_spec=options.tx_subdev_spec,
+        interface=options.interface,
+        mac_addr=options.mac_addr,
+        fusb_block_size=options.fusb_block_size,
+        fusb_nblocks=options.fusb_nblocks,
+        lo_offset=options.lo_offset,
+        gain=options.tx_gain,
+    )
+    if options.show_tx_gain_range:
+        print "Tx Gain Range: minimum = %g, maximum = %g, step size = %g"%tuple(u.gain_range())
+    return u
index 64ce4ec46625e0d9c6dc51a8ec472bbadad0294c..e32180cd493dd8a7caef30810a944dfd22de90c3 100644 (file)
@@ -25,7 +25,6 @@ ourdatadir = $(exampledir)/digital
 
 dist_ourdata_DATA =            \
        README                  \
-       generic_usrp.py         \
        pick_bitrate.py         \
        qt_digital_window.ui    \
        qt_digital_window.py    \
@@ -33,7 +32,6 @@ dist_ourdata_DATA =           \
        qt_rx_window.py         \
        receive_path.py         \
        transmit_path.py        \
-       usrp_options.py \
        usrp_receive_path.py \
        usrp_transmit_path.py
 
index 33cf94a5c5a9235d2a24b04a5d15b797da7d8c0c..0cbb68d23ee5cbde40c086ddb96b96a5b7cd317d 100755 (executable)
@@ -25,6 +25,7 @@ from gnuradio import usrp
 from gnuradio import eng_notation
 from gnuradio.eng_option import eng_option
 from optparse import OptionParser
+from gnuradio import usrp_options
 
 import random
 import struct
@@ -33,7 +34,6 @@ import sys
 # from current dir
 from receive_path import receive_path
 from pick_bitrate import pick_rx_bitrate
-import usrp_options
 
 try:
     from gnuradio.qtgui import qtgui
diff --git a/gnuradio-examples/python/digital/generic_usrp.py b/gnuradio-examples/python/digital/generic_usrp.py
deleted file mode 100644 (file)
index c7ccbe5..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-#
-# Copyright 2009 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-USRP1_TYPE = 'usrp1'
-USRP2_TYPE = 'usrp2'
-DUMMY_TYPE = 'dummy'
-#usrp2 rates common for decim and interp
-_USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4)
-#dummy common rates
-_DUMMY_XRATES = range(4, 512, 2)
-_DUMMY_CONVERTER_RATE = 100e6
-#dummy freq result
-class _dummy_freq_result(object):
-    def __init__(self, target_freq):
-        self.baseband_freq = target_freq
-        self.dxc_freq = 0
-        self.residual_freq = 0
-from gnuradio import gr, usrp, usrp2
-
-########################################################################
-# generic usrp common stuff
-########################################################################
-class _generic_usrp_base(object):
-
-    def __init__(self, which=0, subdev_spec=None, interface="", mac_addr="",
-        fusb_block_size=0, fusb_nblocks=0, usrpx=None, lo_offset=None, gain=None):
-        self._lo_offset = lo_offset
-        #usrp options
-        self._which = which
-        self._subdev_spec = subdev_spec
-        #usrp2 options
-        self._interface = interface
-        self._mac_addr = mac_addr
-        #fusb options
-        self._fusb_block_size = fusb_block_size
-        self._fusb_nblocks = fusb_nblocks
-        #pick which usrp model
-        if usrpx == '0': self._setup_usrpx(DUMMY_TYPE)
-        elif usrpx == '1' or self._subdev_spec: self._setup_usrpx(USRP1_TYPE)
-        elif usrpx == '2' or self._mac_addr: self._setup_usrpx(USRP2_TYPE)
-        else: #automatic
-            try: self._setup_usrpx(USRP2_TYPE)
-            except:
-                try: self._setup_usrpx(USRP1_TYPE)
-                except: raise Exception, 'Failed to automatically setup a usrp device.'
-        #post usrp setup
-        if self._lo_offset is not None:
-            self.set_lo_offset(self._lo_offset)
-        self.set_gain(gain)
-        self.set_auto_tr(True)
-
-    def _setup_usrpx(self, type):
-        """
-        Call the appropriate setup method.
-        @param type the usrp type constant
-        """
-        self._type = type
-        if self._type == USRP1_TYPE: self._setup_usrp1()
-        elif self._type == USRP2_TYPE: self._setup_usrp2()
-        elif self._type == DUMMY_TYPE: self._setup_dummy()
-
-    def __str__(self):
-        if self._type == USRP1_TYPE: return self._subdev.side_and_name()
-        elif self._type == USRP2_TYPE:
-            return 'Interface: %s    MAC Address: %s    D-Board ID: 0x%.2x'%(
-                self._u.interface_name(), self._u.mac_addr(), self._u.daughterboard_id())
-        elif self._type == DUMMY_TYPE: return 'Dummy USRP Device'
-
-    def gain(self): return self._gain
-
-    def set_gain(self, gain=None):
-        #automatic gain calculation
-        r = self.gain_range()
-        if gain is None: gain = (r[0] + r[1])/2 # set gain to midpoint
-        #set gain for usrp
-        self._gain = gain
-        if self._type == USRP1_TYPE: return self._subdev.set_gain(gain)
-        elif self._type == USRP2_TYPE: return self._u.set_gain(gain)
-        elif self._type == DUMMY_TYPE: return True
-
-    def gain_range(self):
-        if self._type == USRP1_TYPE: return self._subdev.gain_range()
-        elif self._type == USRP2_TYPE: return self._u.gain_range()
-        elif self._type == DUMMY_TYPE: return (0, 0, 0)
-
-    def set_center_freq(self, target_freq):
-        if self._type == USRP1_TYPE:
-            return self._u.tune(self._dxc, self._subdev, target_freq)
-        elif self._type == USRP2_TYPE:
-            return self._u.set_center_freq(target_freq)
-        elif self._type == DUMMY_TYPE: return _dummy_freq_result(target_freq)
-
-    def freq_range(self):
-        if self._type == USRP1_TYPE: return self._subdev.freq_range()
-        elif self._type == USRP2_TYPE: return self._u.freq_range()
-        elif self._type == DUMMY_TYPE: return (-10e9, 10e9, 100e3)
-
-    def set_lo_offset(self, lo_offset):
-        if self._type == USRP1_TYPE: return self._subdev.set_lo_offset(lo_offset)
-        elif self._type == USRP2_TYPE: return self._u.set_lo_offset(lo_offset)
-        elif self._type == DUMMY_TYPE: return True
-
-    def set_auto_tr(self, enable):
-        if self._type == USRP1_TYPE: return self._subdev.set_auto_tr(enable)
-
-    def __del__(self):
-        try: # Avoid weak reference error
-            del self._u
-            del self._subdev
-        except: pass
-
-########################################################################
-# generic usrp source
-########################################################################
-class generic_usrp_source_c(_generic_usrp_base, gr.hier_block2):
-    """
-    Create a generic usrp source that represents usrp and usrp2.
-    Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
-    Provide generic access methods so the API looks the same for both.
-    """
-
-    def __init__(self, **kwargs):
-        gr.hier_block2.__init__(self, "generic_usrp_source",
-            gr.io_signature(0, 0, 0), # Input signature
-            gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
-        _generic_usrp_base.__init__(self, **kwargs)
-        self.connect(self._u, self)
-
-    ####################################################################
-    # generic access methods
-    ####################################################################
-    def set_decim(self, decim):
-        if decim not in self.get_decim_rates(): return False
-        if self._type == USRP1_TYPE: return self._u.set_decim_rate(decim)
-        elif self._type == USRP2_TYPE: return self._u.set_decim(decim)
-        elif self._type == DUMMY_TYPE: return True
-
-    def get_decim_rates(self):
-        if self._type == USRP1_TYPE: return range(8, 256+1, 2) #default firmware w/ hb filters
-        if self._type == USRP2_TYPE: return _USRP2_RATES
-        elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
-
-    def adc_rate(self):
-        if self._type == USRP1_TYPE: return self._u.adc_rate()
-        if self._type == USRP2_TYPE: return self._u.adc_rate()
-        elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
-
-    ####################################################################
-    # setup usrp methods
-    ####################################################################
-    def _setup_usrp1(self):
-        self._u = usrp.source_c (self._which,
-                                fusb_block_size=self._fusb_block_size,
-                                fusb_nblocks=self._fusb_nblocks)
-        # determine the daughterboard subdevice we're using
-        if self._subdev_spec is None:
-            self._subdev_spec = usrp.pick_rx_subdevice(self._u)
-        self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
-        self._u.set_mux(usrp.determine_rx_mux_value(self._u, self._subdev_spec))
-        self._dxc = 0
-
-    def _setup_usrp2(self):
-        self._u = usrp2.source_32fc(self._interface, self._mac_addr)
-
-    def _setup_dummy(self): self._u = gr.null_source(gr.sizeof_gr_complex)
-
-########################################################################
-# generic usrp sink
-########################################################################
-class generic_usrp_sink_c(_generic_usrp_base, gr.hier_block2):
-    """
-    Create a generic usrp sink that represents usrp and usrp2.
-    Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
-    Provide generic access methods so the API looks the same for both.
-    """
-
-    def __init__(self, **kwargs):
-        gr.hier_block2.__init__(self, "generic_usrp_sink",
-            gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
-            gr.io_signature(0, 0, 0)) # Output signature
-        _generic_usrp_base.__init__(self, **kwargs)
-        if self._type == USRP1_TYPE: #scale 0.0 to 1.0 input for usrp1
-            self.connect(self, gr.multiply_const_cc((2**15)-1), self._u)
-        else: self.connect(self, self._u)
-
-    ####################################################################
-    # generic access methods
-    ####################################################################
-    def set_interp(self, interp):
-        if interp not in self.get_interp_rates(): return False
-        if self._type == USRP1_TYPE: return self._u.set_interp_rate(interp)
-        elif self._type == USRP2_TYPE: return self._u.set_interp(interp)
-        elif self._type == DUMMY_TYPE: return True
-
-    def get_interp_rates(self):
-        if self._type == USRP1_TYPE: return range(16, 512+1, 4)
-        if self._type == USRP2_TYPE: return _USRP2_RATES
-        elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
-
-    def dac_rate(self):
-        if self._type == USRP1_TYPE: return self._u.dac_rate()
-        if self._type == USRP2_TYPE: return self._u.dac_rate()
-        elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
-
-    ####################################################################
-    # setup usrp methods
-    ####################################################################
-    def _setup_usrp1(self):
-        self._u = usrp.sink_c (self._which,
-                                fusb_block_size=self._fusb_block_size,
-                                fusb_nblocks=self._fusb_nblocks)
-        # determine the daughterboard subdevice we're using
-        if self._subdev_spec is None:
-            self._subdev_spec = usrp.pick_tx_subdevice(self._u)
-        self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
-        self._u.set_mux(usrp.determine_tx_mux_value(self._u, self._subdev_spec))
-        self._dxc = self._subdev.which()
-
-    def _setup_usrp2(self): self._u = usrp2.sink_32fc(self._interface, self._mac_addr)
-
-    def _setup_dummy(self): self._u = gr.null_sink(gr.sizeof_gr_complex)
diff --git a/gnuradio-examples/python/digital/usrp_options.py b/gnuradio-examples/python/digital/usrp_options.py
deleted file mode 100644 (file)
index 380ef60..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-#
-# Copyright 2009 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-_parser_to_groups_dict = dict()
-class _parser_groups(object):
-    def __init__(self, parser):
-        self.usrpx_grp = parser.add_option_group("General USRP Options")
-        self.usrp1_grp = parser.add_option_group("USRP1 Specific Options")
-        self.usrp1exp_grp = parser.add_option_group("USRP1 Expert Options")
-        self.usrp2_grp = parser.add_option_group("USRP2 Specific Options")
-
-import generic_usrp
-
-def _add_options(parser):
-    """
-    Add options to manually choose between usrp or usrp2.
-    Add options for usb. Add options common to source and sink.
-    @param parser: instance of OptionParser
-    @return the parser group
-    """
-    #cache groups so they dont get added twice on tranceiver apps
-    if not _parser_to_groups_dict.has_key(parser): _parser_to_groups_dict[parser] = _parser_groups(parser)
-    pg = _parser_to_groups_dict[parser]
-    #pick usrp or usrp2
-    pg.usrpx_grp.add_option("-u", "--usrpx", type="string", default=None,
-                      help="specify which usrp model: 1 for USRP, 2 for USRP2 [default=auto]")
-    #fast usb options
-    pg.usrp1exp_grp.add_option("-B", "--fusb-block-size", type="int", default=0,
-                      help="specify fast usb block size [default=%default]")
-    pg.usrp1exp_grp.add_option("-N", "--fusb-nblocks", type="int", default=0,
-                      help="specify number of fast usb blocks [default=%default]")
-    #lo offset
-    pg.usrpx_grp.add_option("--lo-offset", type="eng_float", default=None,
-                      help="set LO Offset in Hz [default=automatic].")
-    #usrp options
-    pg.usrp1_grp.add_option("-w", "--which", type="int", default=0,
-                      help="select USRP board [default=%default]")
-    #usrp2 options
-    pg.usrp2_grp.add_option("-e", "--interface", type="string", default="eth0",
-                      help="Use USRP2 at specified Ethernet interface [default=%default]")
-    pg.usrp2_grp.add_option("-a", "--mac-addr", type="string", default="",
-                      help="Use USRP2 at specified MAC address [default=None]")
-    return pg
-
-def add_rx_options(parser):
-    """
-    Add receive specific usrp options.
-    @param parser: instance of OptionParser
-    """
-    pg = _add_options(parser)
-    pg.usrp1_grp.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
-                      help="select USRP Rx side A or B")
-    pg.usrpx_grp.add_option("--rx-gain", type="eng_float", default=None, metavar="GAIN",
-                      help="set receiver gain in dB [default=midpoint].  See also --show-rx-gain-range")
-    pg.usrpx_grp.add_option("--show-rx-gain-range", action="store_true", default=False, 
-                      help="print min and max Rx gain available on selected daughterboard")
-    pg.usrpx_grp.add_option("-d", "--decim", type="intx", default=None,
-                      help="set fpga decimation rate to DECIM [default=%default]")
-
-def create_usrp_source(options):
-    u = generic_usrp.generic_usrp_source_c(
-        usrpx=options.usrpx,
-        which=options.which,
-        subdev_spec=options.rx_subdev_spec,
-        interface=options.interface,
-        mac_addr=options.mac_addr,
-        fusb_block_size=options.fusb_block_size,
-        fusb_nblocks=options.fusb_nblocks,
-        lo_offset=options.lo_offset,
-        gain=options.rx_gain,
-    )
-    if options.show_rx_gain_range:
-        print "Rx Gain Range: minimum = %g, maximum = %g, step size = %g"%tuple(u.gain_range())
-    return u
-
-def add_tx_options(parser):
-    """
-    Add transmit specific usrp options.
-    @param parser: instance of OptionParser
-    """
-    pg = _add_options(parser)
-    pg.usrp1_grp.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
-                      help="select USRP Rx side A or B")
-    pg.usrpx_grp.add_option("--tx-gain", type="eng_float", default=None, metavar="GAIN",
-                      help="set transmitter gain in dB [default=midpoint].  See also --show-tx-gain-range")
-    pg.usrpx_grp.add_option("--show-tx-gain-range", action="store_true", default=False, 
-                      help="print min and max Tx gain available on selected daughterboard")
-    pg.usrpx_grp.add_option("-i", "--interp", type="intx", default=None,
-                      help="set fpga interpolation rate to INTERP [default=%default]")
-
-def create_usrp_sink(options):
-    u = generic_usrp.generic_usrp_sink_c(
-        usrpx=options.usrpx,
-        which=options.which,
-        subdev_spec=options.tx_subdev_spec,
-        interface=options.interface,
-        mac_addr=options.mac_addr,
-        fusb_block_size=options.fusb_block_size,
-        fusb_nblocks=options.fusb_nblocks,
-        lo_offset=options.lo_offset,
-        gain=options.tx_gain,
-    )
-    if options.show_tx_gain_range:
-        print "Tx Gain Range: minimum = %g, maximum = %g, step size = %g"%tuple(u.gain_range())
-    return u
index fd47c2725daee854e14475006cbccae440aa64e4..e28eb0a8cedcbdcfca84a3f69fbacfdb36e80a87 100644 (file)
@@ -20,7 +20,7 @@
 # 
 
 from gnuradio import gr
-import usrp_options
+from gnuradio import usrp_options
 import receive_path
 from pick_bitrate import pick_rx_bitrate
 from gnuradio import eng_notation
index ed2603fa3e632a35580e4559b07440801b06adaa..ad9f741a6309dec1b82106513525ebcb2a324c2f 100644 (file)
@@ -20,7 +20,7 @@
 # 
 
 from gnuradio import gr
-import usrp_options
+from gnuradio import usrp_options
 import transmit_path
 from pick_bitrate import pick_tx_bitrate
 from gnuradio import eng_notation
index 59ca215a764a920392979754e8b5e46b715601fb..fb21e4f449b8eb817a34c792209f1bc2da1029bc 100644 (file)
@@ -50,17 +50,15 @@ bin_SCRIPTS = \
     gr_plot_qt.py \
     gr_filter_design.py \
     lsusrp \
-    qr_fft.py \
     usrp_fft.py \
     usrp_oscope.py \
     usrp_print_db.py \
     usrp_rx_cfile.py \
     usrp_rx_nogui.py \
     usrp_siggen.py \
+    usrp_siggen_gui.py \
     usrp_test_counting.py \
     usrp_test_loopback.py \
     usrp2_fft.py \
-    usrp2_rx_cfile.py \
-    usrp2_siggen.py \
-    usrp2_siggen_gui.py
+    usrp2_rx_cfile.py
 
diff --git a/gr-utils/src/python/qr_fft.py b/gr-utils/src/python/qr_fft.py
deleted file mode 100755 (executable)
index c2f06d7..0000000
+++ /dev/null
@@ -1,505 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2004,2005,2007,2008,2009 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-# 
-
-from gnuradio.wxgui import forms
-from gnuradio import gr, gru
-from gnuradio import vrt
-from gnuradio import eng_notation
-from gnuradio.eng_option import eng_option
-from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider
-from gnuradio.gr import pubsub
-from optparse import OptionParser
-import wx
-import sys
-import numpy
-import time
-
-class app_top_block(stdgui2.std_top_block, pubsub.pubsub):
-    def __init__(self, frame, panel, vbox, argv):
-        stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv)
-        pubsub.pubsub.__init__(self)
-        self.frame = frame
-        self.panel = panel
-        
-        parser = OptionParser(option_class=eng_option)
-        #parser.add_option("-e", "--interface", type="string", default="eth0",
-        #                  help="select Ethernet interface, default is eth0")
-        #parser.add_option("-m", "--mac-addr", type="string", default="",
-        #                  help="select USRP by MAC address, default is auto-select")
-        #parser.add_option("-A", "--antenna", default=None,
-        #                  help="select Rx Antenna (only on RFX-series boards)")
-        #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("-S", "--oscilloscope", action="store_true", default=False,
-                          help="Enable oscilloscope display")
-       parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1,
-                         help="Set fftsink averaging factor, default=[%default]")
-       parser.add_option("", "--ref-scale", type="eng_float", default=1.0,
-                         help="Set dBFS=0dB input value, default=[%default]")
-        parser.add_option("--fft-size", type="int", default=1024,
-                          help="Set number of FFT bins [default=%default]")
-        parser.add_option("--samples-per-pkt", type="int", default=0,
-                          help="Set number of SAMPLES-PER-PKT [default=%default]")
-        parser.add_option("", "--ip-addr", type="string", default="192.168.10.2",
-                          help="IP address default=[%default]")
-        (options, args) = parser.parse_args()
-        if len(args) != 0:
-            parser.print_help()
-            sys.exit(1)
-       self.options = options
-        self.show_debug_info = True
-        
-        self.u = vrt.quadradio_source_32fc(options.ip_addr,
-                                           int(62.5e6), options.samples_per_pkt)
-        #self.u.set_decim(options.decim)
-        
-        #input_rate = self.u.adc_rate() / self.u.decim()
-        input_rate = int(120e6/4)
-        
-        if options.waterfall:
-            self.scope = \
-              waterfallsink2.waterfall_sink_c (panel, fft_size=1024, sample_rate=input_rate)
-        elif options.oscilloscope:
-            self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate)
-        else:
-            self.scope = fftsink2.fft_sink_c (panel,
-                                              fft_size=options.fft_size,
-                                              sample_rate=input_rate, 
-                                             ref_scale=options.ref_scale,
-                                              ref_level=20.0,
-                                              y_divs = 12,
-                                             avg_alpha=options.avg_alpha)
-
-        self.connect(self.u, self.scope)
-
-        self._build_gui(vbox)
-       self._setup_events()
-       
-        # set initial values
-
-        #if options.gain is None:
-        #    # if no gain was specified, use the mid-point in dB
-        #    g = self.u.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.u.freq_range()
-        #    options.freq = float(r[0]+r[1])/2
-            
-        #self.set_gain(options.gain)
-
-       #if options.antenna is not None:
-        #    print "Selecting antenna %s" % (options.antenna,)
-        #    self.subdev.select_rx_antenna(options.antenna)
-
-        if self.show_debug_info:
-        #    self.myform['decim'].set_value(self.u.decim())
-            self.myform['fs@gbe'].set_value(input_rate)
-        #    self.myform['dbname'].set_value("0x%04X" % (self.u.daughterboard_id(),)) # FIXME: add text 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.u.gain_range()
-
-       # some configurations don't have gain control
-       if 0 and g[1] > g[0]:
-           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@gbe'] = form.static_float_field(
-            parent=panel, sizer=hbox, label="Fs@GbE")
-
-        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)
-        ##### db control stuff #####
-        self.subscribe('cal_div_lo_freq', lambda x: self.u.set_lo_freq(x) and time.sleep(0.01))
-        self.subscribe('cal_div_lo_freq', self.u.set_center_freq) #TODO should be combined with set lo freq
-        self.subscribe('cal_div_cal_freq', lambda x: self.u.set_cal_freq(x) and time.sleep(0.01))
-        self.subscribe('db_ctrl_atten0', self.u.set_attenuation0)
-        self.subscribe('db_ctrl_atten1', self.u.set_attenuation1)
-        self.subscribe('sys_beaming', self.u.set_beamforming)
-        #self.subscribe('db_ctrl_10db', self.u.set_10dB_atten)
-        self.subscribe('db_ctrl_adcgain', self.u.set_adc_gain)
-        self.subscribe('db_ctrl_diggain', self.u.set_digital_gain)
-        self.subscribe('db_ctrl_dcoffset', self.u.set_dc_offset_comp)
-        self.subscribe('db_ctrl_bandsel', self.u.set_band_select)
-        self.subscribe('db_ctrl_type', self.u.select_rx_antenna)
-        self.subscribe('db_test_signal', self.u.set_test_signal)
-        self['db_ctrl_bandsel'] = 'A'
-        self['cal_div_lo_freq'] = 2.1e9
-        self['cal_div_cal_freq'] = 2.102e9
-        self['db_ctrl_atten0'] = 0
-        self['db_ctrl_atten1'] = 0
-        #self['db_ctrl_10db'] = False
-        self['db_ctrl_adcgain'] = False
-        self['db_ctrl_dcoffset'] = False
-        self['db_ctrl_diggain'] = 0.0
-        self['db_ctrl_type'] = 'rf'
-        self['db_test_signal'] = vrt.VRT_TEST_SIG_NORMAL
-       self['sys_beaming'] = [16.7e6, 0, 0, 0]
-        #slider and box for freqs
-        for key, name in (('cal_div_lo_freq', 'LO Freq'), ('cal_div_cal_freq', 'Cal Freq')):
-            hbox = wx.BoxSizer(wx.HORIZONTAL)
-            hbox.AddSpacer(10)
-            forms.text_box(
-                label=name,
-                ps=self,
-                key=key,
-                sizer=hbox,
-                parent=panel,
-                proportion=0,
-                converter=forms.float_converter()
-            )
-            hbox.AddSpacer(20)
-            forms.slider(
-                ps=self,
-                key=key,
-                minimum=0,   #TODO get bounds from cal_div, from vrt...
-                maximum=int(3.5e9),
-                step_size=int(5e6),
-                cast=float,
-                sizer=hbox,
-                parent=panel,
-                proportion=2,
-            )
-            hbox.AddSpacer(10)
-            vbox.Add(hbox, 0, wx.EXPAND)
-        ############################################
-        hbox = wx.BoxSizer(wx.HORIZONTAL)
-        hbox.AddSpacer(10)
-        #create slider for atten
-        atten0_txt_box = forms.static_text(
-            label='Attenuation (0)',
-            ps=self,
-            key='db_ctrl_atten0',
-            sizer=hbox,
-            parent=panel,
-            proportion=0,
-            converter=forms.int_converter()
-        )
-        hbox.AddSpacer(20)
-        atten0_slider = forms.slider(
-            ps=self,
-            key='db_ctrl_atten0',
-            minimum=0,
-            maximum=31,
-            step_size=1,
-            cast=int,
-            sizer=hbox,
-            parent=panel,
-            proportion=2,
-        )
-        hbox.AddSpacer(10)
-        #create slider for atten
-        forms.static_text(
-            label='Attenuation (1)',
-            ps=self,
-            key='db_ctrl_atten1',
-            sizer=hbox,
-            parent=panel,
-            proportion=0,
-            converter=forms.int_converter()
-        )
-        hbox.AddSpacer(20)
-        forms.slider(
-            ps=self,
-            key='db_ctrl_atten1',
-            minimum=0,
-            maximum=31,
-            step_size=1,
-            cast=int,
-            sizer=hbox,
-            parent=panel,
-            proportion=2,
-        )
-        hbox.AddSpacer(10)
-        def update_atten0(*args):
-            for form_obj in (atten0_txt_box, atten0_slider): form_obj.Enable(self['db_ctrl_bandsel'] > 'B')
-        update_atten0()
-        self.subscribe('db_ctrl_bandsel', update_atten0)
-        #create checkbox for 10dB att
-        #forms.check_box(
-        #    label='10dB Attenuation',
-        #    ps=self,
-        #    key='db_ctrl_10db',
-        #    sizer=hbox,
-        #    parent=panel,
-        #    proportion=1,
-        #)
-        #hbox.AddSpacer(10)
-        vbox.Add(hbox, 0, wx.EXPAND)
-        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
-        hbox2.AddSpacer(10)
-        forms.static_text(
-            label='ADC Controls',
-            ps=self,
-            key='db_ctrl_diggain',
-            sizer=hbox2,
-            parent=panel,
-            proportion=0,
-            converter=forms.float_converter()
-        )
-        hbox2.AddSpacer(20)
-        #create checkbox for ADC digital gain
-        forms.slider(
-            #label='ADC Digital Gain',
-            ps=self,
-            minimum=0,
-            maximum=6,
-            step_size=0.5,
-            key='db_ctrl_diggain',
-            sizer=hbox2,
-            parent=panel,
-            proportion=2,
-        )
-        hbox2.AddSpacer(10)
-        #create checkbox for 3.5dB ADC gain
-        forms.check_box(
-            label='3.5dB ADC Gain',
-            ps=self,
-            key='db_ctrl_adcgain',
-            sizer=hbox2,
-            parent=panel,
-            proportion=1,
-        )
-        hbox2.AddSpacer(10)
-        #create checkbox for DC Offset Correction in ADC
-        forms.check_box(
-            label='DC Offset Correction',
-            ps=self,
-            key='db_ctrl_dcoffset',
-            sizer=hbox2,
-            parent=panel,
-            proportion=2,
-        )
-        hbox2.AddSpacer(10)
-        vbox.Add(hbox2, 0, wx.EXPAND)
-        hbox = wx.BoxSizer(wx.HORIZONTAL)
-        hbox.AddSpacer(10)
-        #create radio buttons for band sel
-        forms.radio_buttons(
-            label='Band Select',
-            ps=self,
-            key='db_ctrl_bandsel',
-            choices=['A', 'B', 'C', 'D'],
-            labels=['A', 'B', 'C', 'D'],
-            sizer=hbox,
-            parent=panel,
-            proportion=0,
-        )
-        hbox.AddSpacer(10)
-        forms.radio_buttons(
-            label='RF Input',
-            ps=self,
-            key='db_ctrl_type',
-            choices=['rf', 'cal'],
-            labels=['Main RF', 'Calibrator'],
-            sizer=hbox,
-            parent=panel,
-            proportion=0,
-        )
-        hbox.AddSpacer(10)
-        #create radio buttons for band sel
-        types = sorted(
-            filter(lambda x: x.startswith('VRT_TEST_SIG_'), dir(vrt)),
-            lambda x, y: cmp(getattr(vrt, x), getattr(vrt, y)),
-        )
-        forms.drop_down(
-            label='Test Signal',
-            ps=self,
-            key='db_test_signal',
-            choices=map(lambda a: getattr(vrt, a), types),
-            labels=types,
-            sizer=hbox,
-            parent=panel,
-            proportion=0,
-        )
-        hbox.AddSpacer(10)
-        #create radio buttons for type
-        forms.drop_down(
-            label='Beamformer',
-            ps=self,
-            key='sys_beaming',
-            choices=[[16.7e6, 0, 0, 0], [0, 16.7e6, 0, 0], [0, 0, 16.7e6, 0], [0, 0, 0, 16.7e6], [4.19e6]*4],
-            labels=['Ant0', 'Ant1', 'Ant2', 'Ant3', 'Equal Gain'],
-            sizer=hbox,
-            parent=panel,
-            proportion=0,
-        )
-        hbox.AddSpacer(10)
-        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.
-        """
-        return True
-    
-        r = self.u.set_center_freq(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)
-           if not self.options.oscilloscope:
-               self.scope.win.set_baseband_freq(target_freq)
-           return True
-
-        return False
-
-    def set_gain(self, gain):
-        return True
-    
-       if self.myform.has_key('gain'):
-           self.myform['gain'].set_value(gain)     # update displayed value
-        self.u.set_gain(gain)
-
-    def set_decim(self, decim):
-        return True
-    
-        ok = self.u.set_decim(decim)
-        if not ok:
-            print "set_decim failed"
-        #input_rate = self.u.adc_rate() / self.u.decim()
-        input_rate = 120e6/4
-        self.scope.set_sample_rate(input_rate)
-        if self.show_debug_info:  # update displayed values
-            self.myform['decim'].set_value(self.u.decim())
-            self.myform['fs@gbe'].set_value(input_rate)
-        return ok
-
-    def _setup_events(self):
-       if not self.options.waterfall and not self.options.oscilloscope:
-           self.scope.win.Bind(wx.EVT_LEFT_DCLICK, self.evt_left_dclick)
-           
-    def evt_left_dclick(self, event):
-       (ux, uy) = self.scope.win.GetXY(event)
-       if event.CmdDown():
-           # Re-center on maximum power
-           points = self.scope.win._points
-           if self.scope.win.peak_hold:
-               if self.scope.win.peak_vals is not None:
-                   ind = numpy.argmax(self.scope.win.peak_vals)
-               else:
-                   ind = int(points.shape()[0]/2)
-           else:
-               ind = numpy.argmax(points[:,1])
-            (freq, pwr) = points[ind]
-           target_freq = freq/self.scope.win._scale_factor
-           print ind, freq, pwr
-            self.set_freq(target_freq)            
-       else:
-           # Re-center on clicked frequency
-           target_freq = ux/self.scope.win._scale_factor
-           self.set_freq(target_freq)
-           
-       
-def main ():
-    app = stdgui2.stdapp(app_top_block, "QuadRadio FFT", nstatus=1)
-    app.MainLoop()
-
-if __name__ == '__main__':
-    main ()
diff --git a/gr-utils/src/python/usrp2_siggen.py b/gr-utils/src/python/usrp2_siggen.py
deleted file mode 100755 (executable)
index 9ade933..0000000
+++ /dev/null
@@ -1,389 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2008,2009 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-# 
-
-from gnuradio import gr, eng_notation, usrp2
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import sys
-import math
-
-n2s = eng_notation.num_to_str
-
-waveforms = { gr.GR_SIN_WAVE   : "Complex Sinusoid",
-              gr.GR_CONST_WAVE : "Constant",
-              gr.GR_GAUSSIAN   : "Gaussian Noise",
-              gr.GR_UNIFORM    : "Uniform Noise",
-              "2tone"          : "Two Tone",
-              "sweep"          : "Sweep" }
-
-#
-# GUI-unaware GNU Radio flowgraph.  This may be used either with command
-# line applications or GUI applications.
-#
-class top_block(gr.top_block):
-    def __init__(self, options, args):
-        gr.top_block.__init__(self)
-        self._verbose = options.verbose
-
-        self._interp = 0 
-        self._gain = 0
-        self._freq = None       # Indicates frequency hasn't been successfully set yet
-        self._bb_freq = 0
-        self._ddc_freq = 0
-        self._amplitude = 0
-        self._type = None       # Indicates waveform flowgraph not created yet
-        self._offset = options.offset
-
-        self.set_usrp2(options.interface, options.mac_addr)
-        self.set_interp(options.interp)
-        self.set_gain(options.gain)
-        self.set_freq(options.tx_freq, options.lo_offset)
-        self.set_amplitude(options.amplitude)
-
-        self.set_waveform_freq(options.waveform_freq)
-        self.set_waveform2_freq(options.waveform2_freq)
-        self.set_waveform(options.type)
-
-    def set_usrp2(self, interface, mac_addr):
-        self._u = usrp2.sink_32fc(interface, mac_addr)
-        self._dac_rate = self._u.dac_rate()
-        if self._verbose:
-            print "Network interface:", interface
-            print "Network address:", self._u.mac_addr()
-            print "Daughterboard ID:", hex(self._u.daughterboard_id())
-
-    def set_interp(self, interp):
-        if interp < 4 or interp > 512: # FIXME get from flowgraph
-            if self._verbose: print "Interpolation rate out of range:", interp
-            return False
-
-        if not self._u.set_interp(interp):
-            raise RuntimeError("Failed to set interpolation rate %i" % (interp,))
-
-        self._interp = interp
-        self._eth_rate = self._dac_rate/self._interp
-        if self._verbose:
-            print "USRP2 interpolation rate:", self._interp
-            print "USRP2 IF bandwidth: %sHz" % (n2s(self._eth_rate),)
-
-        if (self._type == gr.GR_SIN_WAVE or 
-            self._type == gr.GR_CONST_WAVE):
-            self._src.set_sampling_freq(self._eth_rate)
-        elif self._type == "2tone":
-            self._src1.set_sampling_freq(self._eth_rate)
-            self._src1.set_sampling_freq(self._eth_rate)
-        elif self._type == "sweep":
-            self._src1.set_sampling_freq(self._eth_rate)
-            self._src1.set_sampling_freq(self._waveform_freq*2*math.pi/self._eth_rate)
-        else:
-            return True # Waveform not yet set
-        
-        if self._verbose: print "Set interpolation rate to:", interp
-        return True
-
-    def set_gain(self, gain):
-        if gain is None:
-            g = self._u.gain_range()
-            gain = float(g[0]+g[1])/2
-            if self._verbose:
-                print "Using auto-calculated mid-point TX gain"
-        self._u.set_gain(gain)
-        self._gain = gain
-        if self._verbose:
-            print "Set TX gain to:", self._gain
-
-    def set_freq(self, target_freq, lo_offset=None):
-        if lo_offset is not None:
-            self._lo_offset = lo_offset
-            self._u.set_lo_offset(self._lo_offset)
-            if self._verbose:
-                print "Set LO offset frequency to: %sHz" % (n2s(lo_offset),)
-
-        if target_freq is None:
-            f = self._u.freq_range()
-            target_freq = float(f[0]+f[1])/2.0
-            if self._verbose:
-                print "Using auto-calculated mid-point frequency"
-
-        tr = self._u.set_center_freq(target_freq)
-        fs = "%sHz" % (n2s(target_freq),)
-        if tr is not None:
-            self._freq = target_freq
-
-        else:
-            return True # Waveform not yet set
-        
-        if self._verbose: print "Set amplitude to:", amplitude
-        return True
-
-    def set_gain(self, gain):
-        if gain is None:
-            g = self._u.gain_range()
-            gain = float(g[0]+g[1])/2
-            if self._verbose:
-                print "Using auto-calculated mid-point TX gain"
-        self._u.set_gain(gain)
-        self._gain = gain
-        if self._verbose:
-            print "Set TX gain to:", self._gain
-
-    def set_freq(self, target_freq, lo_offset=None):
-        if lo_offset is not None:
-            self._lo_offset = lo_offset
-            self._u.set_lo_offset(self._lo_offset)
-            if self._verbose:
-                print "Set LO offset frequency to: %sHz" % (n2s(lo_offset),)
-
-        if target_freq is None:
-            f = self._u.freq_range()
-            target_freq = float(f[0]+f[1])/2.0
-            if self._verbose:
-                print "Using auto-calculated mid-point frequency"
-
-        tr = self._u.set_center_freq(target_freq)
-        fs = "%sHz" % (n2s(target_freq),)
-        if tr is not None:
-            self._freq = target_freq
-            self._ddc_freq = tr.dxc_freq
-            self._bb_freq = tr.baseband_freq
-            if self._verbose:
-                print "Set center frequency to", fs
-                print "Tx baseband frequency: %sHz" % (n2s(tr.baseband_freq),)
-                print "Tx DDC frequency: %sHz" % (n2s(tr.dxc_freq),)
-                print "Tx residual frequency: %sHz" % (n2s(tr.residual_freq),)
-                
-        return tr
-
-    def set_waveform_freq(self, freq):
-        self._waveform_freq = freq
-        if self._type == gr.GR_SIN_WAVE:
-            self._src.set_frequency(freq)
-        elif self._type == "2tone" or self._type == "sweep":
-            self._src1.set_frequency(freq)
-        return True
-
-    def set_waveform2_freq(self, freq):
-        self._waveform2_freq = freq
-        if self._type == "2tone":
-            self._src2.set_frequency(freq)
-        elif self._type == "sweep":
-            self._src1.set_frequency(freq)
-        return True
-
-    def set_waveform(self, type):
-        self.lock()
-        self.disconnect_all()
-
-        if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE:
-            self._src = gr.sig_source_c(self._eth_rate,      # Sample rate
-                                        type,                # Waveform type
-                                        self._waveform_freq, # Waveform frequency
-                                        self._amplitude,     # Waveform amplitude
-                                        self._offset)        # Waveform offset
-        elif type == gr.GR_GAUSSIAN or type == gr.GR_UNIFORM:
-            self._src = gr.noise_source_c(type, self._amplitude)
-        elif type == "2tone":
-            self._src1 = gr.sig_source_c(self._eth_rate,
-                                         gr.GR_SIN_WAVE,
-                                         self._waveform_freq,
-                                         self._amplitude/2.0,
-                                         0)
-            if(self._waveform2_freq is None):
-                self._waveform2_freq = -self._waveform_freq
-
-            self._src2 = gr.sig_source_c(self._eth_rate,
-                                         gr.GR_SIN_WAVE,
-                                         self._waveform2_freq,
-                                         self._amplitude/2.0,
-                                         0)
-            self._src = gr.add_cc()
-            self.connect(self._src1,(self._src,0))
-            self.connect(self._src2,(self._src,1))
-        elif type == "sweep":
-            # rf freq is center frequency
-            # waveform_freq is total swept width
-            # waveform2_freq is sweep rate
-            # will sweep from (rf_freq-waveform_freq/2) to (rf_freq+waveform_freq/2)
-            if self._waveform2_freq is None:
-                self._waveform2_freq = 0.1
-
-            self._src1 = gr.sig_source_f(self._eth_rate,
-                                         gr.GR_TRI_WAVE,
-                                         self._waveform2_freq,
-                                         1.0,
-                                         -0.5)
-            self._src2 = gr.frequency_modulator_fc(self._waveform_freq*2*math.pi/self._eth_rate)
-            self._src = gr.multiply_const_cc(self._amplitude)
-            self.connect(self._src1,self._src2,self._src)
-        else:
-            raise RuntimeError("Unknown waveform type")
-
-        self.connect(self._src, self._u)
-        self._type = type
-        self.unlock()
-
-        if self._verbose:
-            print "Set baseband modulation to:", waveforms[self._type]
-            if type == gr.GR_SIN_WAVE:
-                print "Modulation frequency: %sHz" % (n2s(self._waveform_freq),)
-                print "Initial phase:", self._offset
-            elif type == "2tone":
-                print "Tone 1: %sHz" % (n2s(self._waveform_freq),)
-                print "Tone 2: %sHz" % (n2s(self._waveform2_freq),)
-            elif type == "sweep":
-                print "Sweeping across %sHz to %sHz" % (n2s(-self._waveform_freq/2.0),n2s(self._waveform_freq/2.0))
-                print "Sweep rate: %sHz" % (n2s(self._waveform2_freq),)
-            print "TX amplitude:", self._amplitude
-
-
-    def set_amplitude(self, amplitude):
-        if amplitude < 0.0 or amplitude > 1.0:
-            if self._verbose: print "Amplitude out of range:", amplitude
-            return False
-
-        self._amplitude = amplitude
-
-        if (self._type == gr.GR_SIN_WAVE or 
-            self._type == gr.GR_CONST_WAVE or
-            self._type == gr.GR_GAUSSIAN or
-            self._type == gr.GR_UNIFORM):
-            self._src.set_amplitude(amplitude)
-        elif self._type == "2tone":
-            self._src1.set_amplitude(amplitude/2.0)
-            self._src2.set_amplitude(amplitude/2.0)
-        elif self._type == "sweep":
-            self._src.set_k(amplitude)
-        else:
-            return True # Waveform not yet set
-        
-        if self._verbose: print "Set amplitude to:", amplitude
-        return True
-
-
-    # Property getters
-
-    def mac_addr(self):
-        return self._u.mac_addr()
-
-    def interface_name(self):
-        return self._u.interface_name()
-
-    def daughterboard_id(self):
-        return self._u.daughterboard_id()
-
-    def interp_rate(self):
-        return self._interp
-
-    def eth_rate(self):
-        return self._eth_rate
-
-    def freq(self):
-        return self._freq
-
-    def freq_range(self):
-        return self._u.freq_range()
-
-    def ddc_freq(self):
-        return self._ddc_freq
-
-    def baseband_freq(self):
-        return self._bb_freq
-
-    def amplitude(self):
-        return self._amplitude
-
-    def waveform_type(self):
-        return self._type
-
-    def waveform_freq(self):
-        return self._waveform_freq
-
-    def waveform2_freq(self):
-        if self._waveform2_freq is None:
-            return -self._waveform_freq
-        else:
-            return self._waveform2_freq
-
-def get_options():
-    usage="%prog: [options]"
-
-    parser = OptionParser(option_class=eng_option, usage=usage)
-
-    parser.add_option("-e", "--interface", type="string", default="eth0",
-                      help="Use specified Ethernet interface [default=%default]")
-    parser.add_option("-m", "--mac-addr", type="string", default="",
-                      help="Use USRP2 at specified MAC address [default=None]")  
-    parser.add_option("-i", "--interp", type="int", default=16, metavar="INTERP",
-                      help="Set FPGA interpolation rate of INTERP [default=%default]")
-    parser.add_option("-f", "--tx-freq", type="eng_float", default=None,
-                      help="Set carrier frequency to FREQ [default=mid-point]", metavar="FREQ")
-    parser.add_option("--lo-offset", type="eng_float", default=None,
-                      help="set daughterboard LO offset to OFFSET [default=hw default]")
-    parser.add_option("-g", "--gain", type="eng_float", default=None,
-                      help="Set TX gain to GAIN [default=mid-point]")
-    parser.add_option("-w", "--waveform-freq", type="eng_float", default=0,
-                      help="Set baseband waveform frequency to FREQ [default=%default]")
-    parser.add_option("-x", "--waveform2-freq", type="eng_float", default=None,
-                      help="Set 2nd waveform frequency to FREQ [default=%default]")
-    parser.add_option("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE,
-                      help="Generate a carrier modulated by a complex sine wave", default=gr.GR_SIN_WAVE)
-    parser.add_option("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE, 
-                      help="Generate a constant carrier")
-    parser.add_option("--offset", type="eng_float", default=0,
-                      help="Set waveform phase offset to OFFSET [default=%default]")
-    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("--2tone", dest="type", action="store_const", const="2tone",
-                      help="Generate Two Tone signal for IMD testing")
-    parser.add_option("--sweep", dest="type", action="store_const", const="sweep",
-                      help="Generate a swept sine wave")
-    parser.add_option("-a", "--amplitude", type="eng_float", default=0.1,
-                      help="Set output amplitude to AMPL (0.0-1.0) [default=%default]", metavar="AMPL")
-    parser.add_option("-v", "--verbose", action="store_true", default=False,
-                      help="Use verbose console output [default=%default]")
-
-    (options, args) = parser.parse_args()
-
-    return (options, args)
-
-# If this script is executed, the following runs. If it is imported, the below does not run.
-if __name__ == "__main__":
-    if gr.enable_realtime_scheduling() != gr.RT_OK:
-        print "Note: failed to enable realtime scheduling, continuing"
-    
-    # Grab command line options and create top block
-    try:
-        (options, args) = get_options()
-        tb = top_block(options, args)
-
-    except RuntimeError, e:
-        print e
-        sys.exit(1)
-
-    # Run it
-    try:
-        tb.run()
-
-    except KeyboardInterrupt:
-        pass
diff --git a/gr-utils/src/python/usrp2_siggen_gui.py b/gr-utils/src/python/usrp2_siggen_gui.py
deleted file mode 100755 (executable)
index 89bc6e5..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2009 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-# 
-
-import wx
-from gnuradio.wxgui import form, slider, gui
-import usrp2_siggen
-import sys, math
-
-class app_gui(object):
-    def __init__(self, frame, panel, vbox, top_block, options, args):
-        self.frame = frame      # Use for top-level application window frame
-        self.panel = panel      # Use as parent class for created windows
-        self.vbox = vbox        # Use as sizer for created windows
-        self.tb = top_block     # GUI-unaware flowgraph class
-        self.options = options  # Supplied command-line options
-        self.args = args        # Supplied command-line arguments
-
-        freq_range = self.tb.freq_range()
-        self.min_freq = freq_range[0]
-        self.max_freq = freq_range[1]
-        self.freq_step = (self.max_freq-self.min_freq)/100.0
-        self._types = dict([v, k] for k, v in usrp2_siggen.waveforms.items())
-
-        self.build_gui()
-
-        # TODO: turn these into listeners
-        self.myform['ifc'].set_value(self.tb.interface_name())
-        self.myform['mac'].set_value(self.tb.mac_addr())
-        dbid = self.tb.daughterboard_id()
-        self.myform['dbid'].set_value("%04x" % (dbid,))
-
-        w = usrp2_siggen.waveforms[self.tb.waveform_type()]
-        self.myform['type'].set_value(w)
-        self.myform['w1freq'].set_value(self.tb.waveform_freq())
-        self.myform['w2freq'].set_value(self.tb.waveform2_freq())
-
-        freq = self.tb.freq()
-        if freq is None:
-            self.evt_set_status_msg("Failed to set initial frequency")
-        else:
-            self.myform['freq'].set_value(freq)
-            self.myform['freq_slider'].set_value(self.tb.freq())
-
-        amp = self.tb.amplitude()
-        if (amp > 0.0):
-            db = 20*math.log10(amp)
-        else:
-            db = -100.0
-        self.myform['amp'].set_value(amp)
-        self.myform['amp_slider'].set_value(db)
-        self.myform['eth'].set_value(self.tb.eth_rate())
-        self.myform['gbe'].set_value(self.tb.eth_rate()*32)
-        self.myform['interp'].set_value(self.tb.interp_rate())
-        self.myform['DDC'].set_value(self.tb.ddc_freq())
-        self.myform['analog'].set_value(self.tb.baseband_freq())
-
-    # Event response handlers
-    def evt_set_status_msg(self, msg):
-        self.frame.SetStatusText(msg, 0)
-
-    def evt_set_freq1(self, kv):
-        return self.tb.set_waveform_freq(kv['w1freq'])
-
-    def evt_set_freq2(self, kv):
-        return self.tb.set_waveform2_freq(kv['w2freq'])
-
-    def evt_set_freq(self, kv):
-        if type(kv) == type(0.0):              # Set from slider
-            tr = self.tb.set_freq(kv)
-            if tr is not None:
-                self.myform['freq'].set_value(kv)
-        else:                                  # Set from edit box
-            f = kv['freq']
-            tr = self.tb.set_freq(f)
-            if tr is not None:
-                self.myform['freq_slider'].set_value(f)
-
-        if tr is not None:
-            self.myform['DDC'].set_value(tr.dxc_freq)
-            self.myform['analog'].set_value(tr.baseband_freq)
-
-        return (tr is not None)
-
-    def evt_set_amplitude(self, kv):
-        if type(kv) == type(0.0):              # Set from slider
-            amp = math.pow(10, kv/20.0)
-            self.myform['amp'].set_value(amp)
-            return self.tb.set_amplitude(amp)
-        else:                                  # Set from edit box
-            amp = kv['amp']
-            if amp < 0.0 or amp > 1.0:
-                return False
-            if amp == 0.0:
-                db = -100.0
-            else:
-                db = 20*math.log10(amp)
-            self.myform['amp_slider'].set_value(db)
-            return self.tb.set_amplitude(amp)
-
-    def evt_set_interp(self):
-        interp = self.myform['interp'].get_value()
-        if self.tb.set_interp(interp):
-            eth_rate = self.tb.eth_rate()
-            self.myform['eth'].set_value(eth_rate)
-            self.myform['gbe'].set_value(eth_rate*32)
-            return True
-        return False
-
-    def evt_set_waveform_type(self, type):
-        # TODO: update frequency labels
-        return self.tb.set_waveform(self._types[type])
-
-    # GUI construction
-    def build_gui(self):
-        self.myform = myform = form.form()
-
-        # Baseband controls
-        bb_sbox = wx.StaticBox(parent=self.panel, label="Baseband Modulation")
-        bb_vbox = wx.StaticBoxSizer(bb_sbox, wx.VERTICAL) # Holds all baseband controls as unit
-
-        # First row of baseband controls (modulation type)
-        mod_hbox = wx.BoxSizer(wx.HORIZONTAL)
-        mod_hbox.Add((10,0), 0, 0)
-        myform['type'] = form.radiobox_field(
-            parent=self.panel, label="Type", sizer=mod_hbox, value=None,
-            callback=self.evt_set_waveform_type, weight=1, major_dimension=0,
-            choices=usrp2_siggen.waveforms.values() )
-        bb_vbox.Add((0,10), 0, 0)
-        bb_vbox.Add(mod_hbox, 0, wx.EXPAND)
-
-        # Second row of baseband controls (frequencies)
-        bbf_hbox = wx.BoxSizer(wx.HORIZONTAL)
-        bbf_hbox.Add((10,0), 0, 0)
-        myform['w1freq'] = form.float_field(
-            parent=self.panel, sizer=bbf_hbox, label="Frequency 1 (Hz)", weight=1,
-            callback=myform.check_input_and_call(self.evt_set_freq1, self.evt_set_status_msg) )
-        bbf_hbox.Add((10,0), 0, 0)
-        myform['w2freq'] = form.float_field(
-            parent=self.panel, sizer=bbf_hbox, label="Frequency 2 (Hz)", weight=1,
-            callback=myform.check_input_and_call(self.evt_set_freq2, self.evt_set_status_msg) )
-        bbf_hbox.Add((10,0), 0, 0)
-        
-        bb_vbox.Add((0,10), 0, 0)
-        bb_vbox.Add(bbf_hbox, 0, wx.EXPAND)
-
-        # Add baseband controls to top window sizer
-        self.vbox.Add((0,10), 0, 0)
-        self.vbox.Add(bb_vbox, 0, wx.EXPAND)
-
-        # Frequency controls
-        fc_sbox = wx.StaticBox(parent=self.panel, label="Center Frequency")
-        fc_vbox = wx.StaticBoxSizer(fc_sbox, wx.VERTICAL) # Holds all frequency controls as unit
-
-        # First row of frequency controls (center frequency)
-        freq_hbox = wx.BoxSizer(wx.HORIZONTAL)
-        freq_hbox.Add((10,0), 0, 0)
-        myform['freq'] = form.float_field(
-            parent=self.panel, sizer=freq_hbox, label=None, weight=1,
-            callback=myform.check_input_and_call(self.evt_set_freq, self.evt_set_status_msg) )
-        freq_hbox.Add((10,0), 0, 0)
-        myform['freq_slider'] = form.quantized_slider_field(
-            parent=self.panel, sizer=freq_hbox, label="Min-Max", weight=4,
-            range = (self.min_freq, self.max_freq, self.freq_step),
-            callback=self.evt_set_freq)
-        freq_hbox.Add((10,0), 0, 0)
-
-        fc_vbox.Add((10,0), 0, 0)
-        fc_vbox.Add(freq_hbox, 0, wx.EXPAND)
-
-        # Second row of frequency controls (results)
-        tr_hbox = wx.BoxSizer(wx.HORIZONTAL)
-        tr_hbox.Add((10,0), 0, 0)
-        myform['analog'] = form.static_float_field(
-            parent=self.panel, sizer=tr_hbox, label="Daughterboard: (Hz)", weight=1)
-        tr_hbox.Add((10,0), 0, 0)
-        myform['DDC'] = form.static_float_field(
-            parent=self.panel, sizer=tr_hbox, label="USRP2 DDC (Hz)", weight=1)
-        tr_hbox.Add((10,0), 0, 0)
-        fc_vbox.Add(tr_hbox, 0, wx.EXPAND)
-
-        # Add frequency controls to top window sizer
-        self.vbox.Add((0,10), 0, 0)
-        self.vbox.Add(fc_vbox, 0, wx.EXPAND)
-
-        # Amplitude row
-        amp_sbox = wx.StaticBox(parent=self.panel, label="Amplitude")
-        amp_hbox = wx.StaticBoxSizer(amp_sbox, wx.HORIZONTAL)
-        amp_hbox.Add((10,0), 0, 0)
-        myform['amp'] = form.float_field(
-            parent=self.panel, sizer=amp_hbox, label="Linear\n(0.0-1.0)", weight=1,
-            callback=myform.check_input_and_call(self.evt_set_amplitude, self.evt_set_status_msg) )
-        amp_hbox.Add((10,0), 0, 0)
-        myform['amp_slider'] = form.quantized_slider_field(
-            parent=self.panel, sizer=amp_hbox, label="dB Full Scale\n(-100-0)", weight=4,
-            range=(-100.0, 0.0, 1), callback=self.evt_set_amplitude)
-        amp_hbox.Add((10,0), 0, 0)
-        self.vbox.Add((0,10), 0, 0)
-        self.vbox.Add(amp_hbox, 0, wx.EXPAND)
-
-        # Sample rate row
-        sam_sbox = wx.StaticBox(parent=self.panel, label="Sample Rate")
-        sam_hbox = wx.StaticBoxSizer(sam_sbox, wx.HORIZONTAL)
-        sam_hbox.Add((10,0), 0, 0)
-        myform['interp'] = form.int_field(
-            parent=self.panel, sizer=sam_hbox, label="Interpolation", weight=1,
-            callback=self.evt_set_interp)
-        sam_hbox.Add((10,0), 0, 0)
-        myform['eth'] = form.static_float_field(
-            parent=self.panel, sizer=sam_hbox, label="Sample Rate (sps)", weight=1)
-        sam_hbox.Add((10,0), 0, 0)
-        myform['gbe'] = form.static_float_field(
-            parent=self.panel, sizer=sam_hbox, label="GbE Rate (bits/sec)", weight=1)
-        sam_hbox.Add((10,0), 0, 0)
-        self.vbox.Add((0,10), 0, 0)
-        self.vbox.Add(sam_hbox, 0, wx.EXPAND)
-
-        # USRP2 row
-        u2_sbox = wx.StaticBox(parent=self.panel, label="USRP2 Hardware")
-        u2_hbox = wx.StaticBoxSizer(u2_sbox, wx.HORIZONTAL)
-        u2_hbox.Add((10,0), 0, 0)
-        myform['ifc'] = form.static_text_field(parent=self.panel, sizer=u2_hbox, 
-                                               label="Interface", weight=2)
-        u2_hbox.Add((10,0), 0, 0)
-        myform['mac'] = form.static_text_field(parent=self.panel, sizer=u2_hbox, 
-                                               label="MAC Address", weight=2)
-        u2_hbox.Add((10,0), 0, 0)
-        myform['dbid'] = form.static_text_field(parent=self.panel, sizer=u2_hbox, 
-                                                label="Daughterboard ID", weight=1)
-        self.vbox.Add((0,10), 0, 0)
-        self.vbox.Add(u2_hbox, 0, wx.EXPAND)
-        self.vbox.Add((0,20), 0, 0)
-
-if __name__ == "__main__":
-    try:
-        # Get command line parameters
-        (options, args) = usrp2_siggen.get_options()
-
-        # Create the top block using these
-        tb = usrp2_siggen.top_block(options, args)
-
-        # Create the GUI application
-        app = gui.app(top_block=tb,                    # Constructed top block
-                      gui=app_gui,                     # User interface class
-                      options=options,                 # Command line options
-                      args=args,                       # Command line args
-                      title="USRP2 Signal Generator",  # Top window title
-                      nstatus=1,                       # Number of status lines
-                      start=True,                      # Whether to start flowgraph
-                      realtime=True)                   # Whether to set realtime priority
-
-        # And run it
-        app.MainLoop()
-
-    except RuntimeError, e:
-        print e
-        sys.exit(1)
index 8ae2fbfbfd93ade4518cff28311ab3ba946108d6..8ee8cfd2ad4696d9fd1ba586dc8d62e8c96da9c3 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2004,2005,2007,2008 Free Software Foundation, Inc.
+# Copyright 2008,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
 # Boston, MA 02110-1301, USA.
 # 
 
-from gnuradio import gr, gru
-from gnuradio import usrp
+DESC_KEY = 'desc'
+SAMP_RATE_KEY = 'samp_rate'
+LINK_RATE_KEY = 'link_rate'
+DAC_RATE_KEY = 'dac_rate'
+INTERP_KEY = 'interp'
+GAIN_KEY = 'gain'
+TX_FREQ_KEY = 'tx_freq'
+DDC_FREQ_KEY = 'ddc_freq'
+BB_FREQ_KEY = 'bb_freq'
+AMPLITUDE_KEY = 'amplitude'
+AMPL_RANGE_KEY = 'ampl_range'
+WAVEFORM_FREQ_KEY = 'waveform_freq'
+WAVEFORM_OFFSET_KEY = 'waveform_offset'
+WAVEFORM2_FREQ_KEY = 'waveform2_freq'
+FREQ_RANGE_KEY = 'freq_range'
+GAIN_RANGE_KEY = 'gain_range'
+TYPE_KEY = 'type'
+
+def setter(ps, key, val): ps[key] = val
+
+from gnuradio import gr, eng_notation
+from gnuradio.gr.pubsub import pubsub
 from gnuradio.eng_option import eng_option
-from gnuradio import eng_notation
+from gnuradio import usrp_options
 from optparse import OptionParser
 import sys
+import math
 
+n2s = eng_notation.num_to_str
 
-class my_top_block(gr.top_block):
-    def __init__ (self, nsamples):
+waveforms = { gr.GR_SIN_WAVE   : "Complex Sinusoid",
+              gr.GR_CONST_WAVE : "Constant",
+              gr.GR_GAUSSIAN   : "Gaussian Noise",
+              gr.GR_UNIFORM    : "Uniform Noise",
+              "2tone"          : "Two Tone",
+              "sweep"          : "Sweep" }
+
+#
+# GUI-unaware GNU Radio flowgraph.  This may be used either with command
+# line applications or GUI applications.
+#
+class top_block(gr.top_block, pubsub):
+    def __init__(self, options, args):
         gr.top_block.__init__(self)
+        pubsub.__init__(self)
+        self._verbose = options.verbose
+        #initialize values from options
+        self._setup_usrpx(options)
+        self.subscribe(INTERP_KEY, lambda i: setter(self, SAMP_RATE_KEY, self[DAC_RATE_KEY]/i))
+        self.subscribe(SAMP_RATE_KEY, lambda e: setter(self, LINK_RATE_KEY, e*32))
+        self[INTERP_KEY] = options.interp or 16
+        self[TX_FREQ_KEY] = options.tx_freq
+        self[AMPLITUDE_KEY] = options.amplitude
+        self[WAVEFORM_FREQ_KEY] = options.waveform_freq
+        self[WAVEFORM_OFFSET_KEY] = options.offset
+        self[WAVEFORM2_FREQ_KEY] = options.waveform2_freq
+        self[BB_FREQ_KEY] = 0
+        self[DDC_FREQ_KEY] = 0
+        #subscribe set methods
+        self.subscribe(INTERP_KEY, self.set_interp)
+        self.subscribe(GAIN_KEY, self.set_gain)
+        self.subscribe(TX_FREQ_KEY, self.set_freq)
+        self.subscribe(AMPLITUDE_KEY, self.set_amplitude)
+        self.subscribe(WAVEFORM_FREQ_KEY, self.set_waveform_freq)
+        self.subscribe(WAVEFORM2_FREQ_KEY, self.set_waveform2_freq)
+        self.subscribe(TYPE_KEY, self.set_waveform)
+        #force update on pubsub keys
+        for key in (INTERP_KEY, GAIN_KEY, TX_FREQ_KEY,
+            AMPLITUDE_KEY, WAVEFORM_FREQ_KEY, WAVEFORM_OFFSET_KEY, WAVEFORM2_FREQ_KEY):
+            self[key] = self[key]
+        self[TYPE_KEY] = options.type #set type last
+
+    def _setup_usrpx(self, options):
+        self._u = usrp_options.create_usrp_sink(options)
+        self.publish(DESC_KEY, lambda: str(self._u))
+        self.publish(DAC_RATE_KEY, self._u.dac_rate)
+        self.publish(FREQ_RANGE_KEY, self._u.freq_range)
+        self.publish(GAIN_RANGE_KEY, self._u.gain_range)
+        self.publish(GAIN_KEY, self._u.gain)
+        if self._verbose: print str(self._u)
+
+    def _set_tx_amplitude(self, ampl):
+        """
+        Sets the transmit amplitude sent to the USRP
+        @param ampl the amplitude or None for automatic
+        """
+        ampl_range = self[AMPL_RANGE_KEY]
+        if ampl is None: ampl = (ampl_range[1] - ampl_range[0])*0.15 + ampl_range[0]
+        self[AMPLITUDE_KEY] = max(ampl_range[0], min(ampl, ampl_range[1]))
+
+    def set_interp(self, interp):
+        if not self._u.set_interp(interp):
+            raise RuntimeError("Failed to set interpolation rate %i" % (interp,))
+
+        if self._verbose:
+            print "USRP interpolation rate:", interp
+            print "USRP IF bandwidth: %sHz" % (n2s(self[SAMP_RATE_KEY]),)
+
+        if self[TYPE_KEY] in (gr.GR_SIN_WAVE, gr.GR_CONST_WAVE):
+            self._src.set_sampling_freq(self[SAMP_RATE_KEY])
+        elif self[TYPE_KEY] == "2tone":
+            self._src1.set_sampling_freq(self[SAMP_RATE_KEY])
+            self._src2.set_sampling_freq(self[SAMP_RATE_KEY])
+        elif self[TYPE_KEY] == "sweep":
+            self._src1.set_sampling_freq(self[SAMP_RATE_KEY])
+            self._src2.set_sampling_freq(self[WAVEFORM_FREQ_KEY]*2*math.pi/self[SAMP_RATE_KEY])
+        else:
+            return True # Waveform not yet set
         
-        # 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.nsamples = nsamples
-        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.head = None
-        if self.nsamples > 0:
-            self.head = gr.head(gr.sizeof_gr_complex, int(self.nsamples))
-
-        # self.file_sink = gr.file_sink (gr.sizeof_gr_complex, "siggen.dat")
-
-    def _configure_graph (self, type):
-        try:
-            self.lock()
-            self.disconnect_all ()
-
-            if self.head:
-                self.connect(self.head, self.u)
-                tail = self.head
-            else:
-                tail = self.u
-                
-            if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE:
-                self.connect (self.siggen, tail)
-                # 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, tail)
-                self.noisegen.set_type (type)
-                self.src = self.noisegen
-            else:
-                raise ValueError, type
-        finally:
-            self.unlock()
+        if self._verbose: print "Set interpolation rate to:", interp
+        return True
+
+    def set_gain(self, gain):
+        if gain is None:
+            g = self[GAIN_RANGE_KEY]
+            gain = float(g[0]+g[1])/2
+            if self._verbose:
+                print "Using auto-calculated mid-point TX gain"
+            self[GAIN_KEY] = gain
+            return
+        self._u.set_gain(gain)
+        if self._verbose:
+            print "Set TX gain to:", 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.
-        """
-        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 [default=%default]")
-
-    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=0,
-                       help="set waveform frequency to FREQ [default=%default]")
-    parser.add_option ("-a", "--amplitude", type="eng_float", default=16e3,
-                       help="set waveform amplitude to AMPLITUDE [default=%default]", metavar="AMPL")
-    parser.add_option ("-g", "--gain", type="eng_float", default=None,
-                       help="set output gain to GAIN [default=%default]")
-    parser.add_option ("-o", "--offset", type="eng_float", default=0,
-                       help="set waveform offset to OFFSET [default=%default]")
-    parser.add_option ("-N", "--nsamples", type="eng_float", default=0,
-                       help="set number of samples to transmit [default=+inf]")
-    (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
-
-    tb = my_top_block(options.nsamples)
-    tb.set_interpolator (options.interp)
-    tb.set_waveform_type (options.type)
-    tb.set_waveform_freq (options.waveform_freq)
-    tb.set_waveform_ampl (options.amplitude)
-    tb.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(tb.u)
-
-    m = usrp.determine_tx_mux_value(tb.u, options.tx_subdev_spec)
-    #print "mux = %#04x" % (m,)
-    tb.u.set_mux(m)
-    tb.subdev = usrp.selected_subdev(tb.u, options.tx_subdev_spec)
-    print "Using TX d'board %s" % (tb.subdev.side_and_name(),)
-    
-    if options.gain is None:
-        tb.subdev.set_gain(tb.subdev.gain_range()[1])    # set max Tx gain
-    else:
-        tb.subdev.set_gain(options.gain)    # set max Tx gain
-
-    if not tb.set_freq(options.rf_freq):
-        sys.stderr.write('Failed to set RF frequency\n')
-        raise SystemExit
+        if target_freq is None:
+            f = self[FREQ_RANGE_KEY]
+            target_freq = float(f[0]+f[1])/2.0
+            if self._verbose:
+                print "Using auto-calculated mid-point frequency"
+            self[TX_FREQ_KEY] = target_freq
+            return
+
+        tr = self._u.set_center_freq(target_freq)
+        fs = "%sHz" % (n2s(target_freq),)
+        if tr is not None:
+            self._freq = target_freq
+            self[DDC_FREQ_KEY] = tr.dxc_freq
+            self[BB_FREQ_KEY] = tr.baseband_freq
+            if self._verbose:
+                print "Set center frequency to", fs
+                print "Tx baseband frequency: %sHz" % (n2s(tr.baseband_freq),)
+                print "Tx DDC frequency: %sHz" % (n2s(tr.dxc_freq),)
+                print "Tx residual frequency: %sHz" % (n2s(tr.residual_freq),)
+        elif self._verbose: print "Failed to set freq." 
+        return tr
+
+    def set_waveform_freq(self, freq):
+        if self[TYPE_KEY] == gr.GR_SIN_WAVE:
+            self._src.set_frequency(freq)
+        elif self[TYPE_KEY] == "2tone":
+            self._src1.set_frequency(freq)
+        elif self[TYPE_KEY] == 'sweep':
+            #there is no set sensitivity, redo fg
+            self[TYPE_KEY] = self[TYPE_KEY]
+        return True
+
+    def set_waveform2_freq(self, freq):
+        if freq is None:
+            self[WAVEFORM2_FREQ_KEY] = -self[WAVEFORM_FREQ_KEY]
+            return
+        if self[TYPE_KEY] == "2tone":
+            self._src2.set_frequency(freq)
+        elif self[TYPE_KEY] == "sweep":
+            self._src1.set_frequency(freq)
+        return True
+
+    def set_waveform(self, type):
+        self.lock()
+        self.disconnect_all()
+        if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE:
+            self._src = gr.sig_source_c(self[SAMP_RATE_KEY],      # Sample rate
+                                        type,                # Waveform type
+                                        self[WAVEFORM_FREQ_KEY], # Waveform frequency
+                                        self[AMPLITUDE_KEY],     # Waveform amplitude
+                                        self[WAVEFORM_OFFSET_KEY])        # Waveform offset
+        elif type == gr.GR_GAUSSIAN or type == gr.GR_UNIFORM:
+            self._src = gr.noise_source_c(type, self[AMPLITUDE_KEY])
+        elif type == "2tone":
+            self._src1 = gr.sig_source_c(self[SAMP_RATE_KEY],
+                                         gr.GR_SIN_WAVE,
+                                         self[WAVEFORM_FREQ_KEY],
+                                         self[AMPLITUDE_KEY]/2.0,
+                                         0)
+            if(self[WAVEFORM2_FREQ_KEY] is None):
+                self[WAVEFORM2_FREQ_KEY] = -self[WAVEFORM_FREQ_KEY]
+
+            self._src2 = gr.sig_source_c(self[SAMP_RATE_KEY],
+                                         gr.GR_SIN_WAVE,
+                                         self[WAVEFORM2_FREQ_KEY],
+                                         self[AMPLITUDE_KEY]/2.0,
+                                         0)
+            self._src = gr.add_cc()
+            self.connect(self._src1,(self._src,0))
+            self.connect(self._src2,(self._src,1))
+        elif type == "sweep":
+            # rf freq is center frequency
+            # waveform_freq is total swept width
+            # waveform2_freq is sweep rate
+            # will sweep from (rf_freq-waveform_freq/2) to (rf_freq+waveform_freq/2)
+            if self[WAVEFORM2_FREQ_KEY] is None:
+                self[WAVEFORM2_FREQ_KEY] = 0.1
+
+            self._src1 = gr.sig_source_f(self[SAMP_RATE_KEY],
+                                         gr.GR_TRI_WAVE,
+                                         self[WAVEFORM2_FREQ_KEY],
+                                         1.0,
+                                         -0.5)
+            self._src2 = gr.frequency_modulator_fc(self[WAVEFORM_FREQ_KEY]*2*math.pi/self[SAMP_RATE_KEY])
+            self._src = gr.multiply_const_cc(self[AMPLITUDE_KEY])
+            self.connect(self._src1,self._src2,self._src)
+        else:
+            raise RuntimeError("Unknown waveform type")
+
+        self.connect(self._src, self._u)
+        self.unlock()
+
+        if self._verbose:
+            print "Set baseband modulation to:", waveforms[type]
+            if type == gr.GR_SIN_WAVE:
+                print "Modulation frequency: %sHz" % (n2s(self[WAVEFORM_FREQ_KEY]),)
+                print "Initial phase:", self[WAVEFORM_OFFSET_KEY]
+            elif type == "2tone":
+                print "Tone 1: %sHz" % (n2s(self[WAVEFORM_FREQ_KEY]),)
+                print "Tone 2: %sHz" % (n2s(self[WAVEFORM2_FREQ_KEY]),)
+            elif type == "sweep":
+                print "Sweeping across %sHz to %sHz" % (n2s(-self[WAVEFORM_FREQ_KEY]/2.0),n2s(self[WAVEFORM_FREQ_KEY]/2.0))
+                print "Sweep rate: %sHz" % (n2s(self[WAVEFORM2_FREQ_KEY]),)
+            print "TX amplitude:", self[AMPLITUDE_KEY]
+
+
+    def set_amplitude(self, amplitude):
+        if amplitude < 0.0 or amplitude > 1.0:
+            if self._verbose: print "Amplitude out of range:", amplitude
+            return False
+
+        if self[TYPE_KEY] in (gr.GR_SIN_WAVE, gr.GR_CONST_WAVE, gr.GR_GAUSSIAN, gr.GR_UNIFORM):
+            self._src.set_amplitude(amplitude)
+        elif self[TYPE_KEY] == "2tone":
+            self._src1.set_amplitude(amplitude/2.0)
+            self._src2.set_amplitude(amplitude/2.0)
+        elif self[TYPE_KEY] == "sweep":
+            self._src.set_k(amplitude)
+        else:
+            return True # Waveform not yet set
+        
+        if self._verbose: print "Set amplitude to:", amplitude
+        return True
+
+def get_options():
+    usage="%prog: [options]"
+
+    parser = OptionParser(option_class=eng_option, usage=usage)
+    usrp_options.add_tx_options(parser)
+    parser.add_option("-f", "--tx-freq", type="eng_float", default=None,
+                      help="Set carrier frequency to FREQ [default=mid-point]", metavar="FREQ")
+    parser.add_option("-x", "--waveform-freq", type="eng_float", default=0,
+                      help="Set baseband waveform frequency to FREQ [default=%default]")
+    parser.add_option("-y", "--waveform2-freq", type="eng_float", default=None,
+                      help="Set 2nd waveform frequency to FREQ [default=%default]")
+    parser.add_option("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE,
+                      help="Generate a carrier modulated by a complex sine wave", default=gr.GR_SIN_WAVE)
+    parser.add_option("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE, 
+                      help="Generate a constant carrier")
+    parser.add_option("--offset", type="eng_float", default=0,
+                      help="Set waveform phase offset to OFFSET [default=%default]")
+    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("--2tone", dest="type", action="store_const", const="2tone",
+                      help="Generate Two Tone signal for IMD testing")
+    parser.add_option("--sweep", dest="type", action="store_const", const="sweep",
+                      help="Generate a swept sine wave")
+    parser.add_option("-A", "--amplitude", type="eng_float", default=0.15,
+                      help="Set output amplitude to AMPL (0.0-1.0) [default=%default]", metavar="AMPL")
+    parser.add_option("-v", "--verbose", action="store_true", default=False,
+                      help="Use verbose console output [default=%default]")
+
+    (options, args) = parser.parse_args()
+
+    return (options, args)
+
+# If this script is executed, the following runs. If it is imported, the below does not run.
+if __name__ == "__main__":
+    if gr.enable_realtime_scheduling() != gr.RT_OK:
+        print "Note: failed to enable realtime scheduling, continuing"
     
-    tb.subdev.set_enable(True)                       # enable transmitter
+    # Grab command line options and create top block
+    try:
+        (options, args) = get_options()
+        tb = top_block(options, args)
 
+    except RuntimeError, e:
+        print e
+        sys.exit(1)
+
+    # Run it
     try:
         tb.run()
+
     except KeyboardInterrupt:
         pass
-
-
-if __name__ == '__main__':
-    main ()
diff --git a/gr-utils/src/python/usrp_siggen_gui.py b/gr-utils/src/python/usrp_siggen_gui.py
new file mode 100755 (executable)
index 0000000..40848fb
--- /dev/null
@@ -0,0 +1,310 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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 3, 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., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+import wx
+from gnuradio import gr
+from gnuradio.gr.pubsub import pubsub
+from gnuradio.wxgui import gui, forms
+import usrp_siggen
+import sys, math
+
+class app_gui(pubsub):
+    def __init__(self, frame, panel, vbox, top_block, options, args):
+        pubsub.__init__(self)
+        self.frame = frame      # Use for top-level application window frame
+        self.panel = panel      # Use as parent class for created windows
+        self.vbox = vbox        # Use as sizer for created windows
+        self.tb = top_block     # GUI-unaware flowgraph class
+        self.options = options  # Supplied command-line options
+        self.args = args        # Supplied command-line arguments
+        self.build_gui()
+
+    # Event response handlers
+    def evt_set_status_msg(self, msg):
+        self.frame.SetStatusText(msg, 0)
+
+    # GUI construction
+    def build_gui(self):
+        self.vbox.AddSpacer(5)
+        self.vbox.AddStretchSpacer()
+        ##################################################
+        # Baseband controls
+        ##################################################
+        bb_vbox = forms.static_box_sizer(parent=self.panel, label="Baseband Modulation", orient=wx.VERTICAL, bold=True)
+        self.vbox.Add(bb_vbox, 0, wx.EXPAND)
+        sine_bb_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        sweep_bb_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        tone_bb_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        self.vbox.AddSpacer(10)
+        self.vbox.AddStretchSpacer()
+        #callback to show/hide forms
+        def set_type(type):
+            sine_bb_hbox.ShowItems(type == gr.GR_SIN_WAVE)
+            sweep_bb_hbox.ShowItems(type == 'sweep')
+            tone_bb_hbox.ShowItems(type == '2tone')
+            self.vbox.Layout()
+        self.tb.subscribe(usrp_siggen.TYPE_KEY, set_type)
+        #create sine forms
+        sine_bb_hbox.AddSpacer(10)
+        forms.text_box(
+            parent=self.panel, sizer=sine_bb_hbox,
+            label='Frequency (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.WAVEFORM_FREQ_KEY,
+            converter=forms.float_converter(),
+        )
+        sine_bb_hbox.AddStretchSpacer()
+        #create sweep forms
+        sweep_bb_hbox.AddSpacer(10)
+        forms.text_box(
+            parent=self.panel, sizer=sweep_bb_hbox,
+            label='Sweep Width (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.WAVEFORM_FREQ_KEY,
+            converter=forms.float_converter(),
+        )
+        sweep_bb_hbox.AddStretchSpacer()
+        forms.text_box(
+            parent=self.panel, sizer=sweep_bb_hbox,
+            label='Sweep Rate (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.WAVEFORM2_FREQ_KEY,
+            converter=forms.float_converter(),
+        )
+        sweep_bb_hbox.AddStretchSpacer()
+        #create 2tone forms
+        tone_bb_hbox.AddSpacer(10)
+        forms.text_box(
+            parent=self.panel, sizer=tone_bb_hbox,
+            label='Tone 1 (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.WAVEFORM_FREQ_KEY,
+            converter=forms.float_converter(),
+        )
+        tone_bb_hbox.AddStretchSpacer()
+        forms.text_box(
+            parent=self.panel, sizer=tone_bb_hbox,
+            label='Tone 2 (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.WAVEFORM2_FREQ_KEY,
+            converter=forms.float_converter(),
+        )
+        tone_bb_hbox.AddStretchSpacer()
+        forms.radio_buttons(
+            parent=self.panel, sizer=bb_vbox,
+            choices=usrp_siggen.waveforms.keys(),
+            labels=usrp_siggen.waveforms.values(),
+            ps=self.tb,
+            key=usrp_siggen.TYPE_KEY,
+            style=wx.NO_BORDER | wx.RA_HORIZONTAL,
+        )
+        bb_vbox.AddSpacer(10)
+        bb_vbox.Add(sine_bb_hbox, 0, wx.EXPAND)
+        bb_vbox.Add(sweep_bb_hbox, 0, wx.EXPAND)
+        bb_vbox.Add(tone_bb_hbox, 0, wx.EXPAND)
+        set_type(self.tb[usrp_siggen.TYPE_KEY])
+        ##################################################
+        # Frequency controls
+        ##################################################
+        fc_vbox = forms.static_box_sizer(parent=self.panel, label="Center Frequency", orient=wx.VERTICAL, bold=True)
+        fc_vbox.AddSpacer(5)
+        # First row of frequency controls (center frequency)
+        freq_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        fc_vbox.Add(freq_hbox, 0, wx.EXPAND)
+        fc_vbox.AddSpacer(10)
+        # Second row of frequency controls (results)
+        tr_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        fc_vbox.Add(tr_hbox, 0, wx.EXPAND)
+        fc_vbox.AddSpacer(5)
+        # Add frequency controls to top window sizer
+        self.vbox.Add(fc_vbox, 0, wx.EXPAND)
+        self.vbox.AddSpacer(10)
+        self.vbox.AddStretchSpacer()
+        freq_hbox.AddSpacer(5)
+        forms.text_box(
+            parent=self.panel, sizer=freq_hbox,
+            proportion=1,
+            converter=forms.float_converter(),
+            ps=self.tb,
+            key=usrp_siggen.TX_FREQ_KEY,
+        )
+        freq_hbox.AddSpacer(10)
+        forms.slider(
+            parent=self.panel, sizer=freq_hbox,
+            proportion=2,
+            ps=self.tb,
+            key=usrp_siggen.TX_FREQ_KEY,
+            minimum=self.tb[usrp_siggen.FREQ_RANGE_KEY][0],
+            maximum=self.tb[usrp_siggen.FREQ_RANGE_KEY][1],
+            num_steps=100,
+        )
+        freq_hbox.AddSpacer(5)
+        tr_hbox.AddSpacer(5)
+        forms.static_text(
+            parent=self.panel, sizer=tr_hbox,
+            label='Daughterboard (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.BB_FREQ_KEY,
+            converter=forms.float_converter(),
+            proportion=1,
+        )
+        tr_hbox.AddSpacer(10)
+        forms.static_text(
+            parent=self.panel, sizer=tr_hbox,
+            label='USRP DDC (Hz)',
+            ps=self.tb,
+            key=usrp_siggen.DDC_FREQ_KEY,
+            converter=forms.float_converter(),
+            proportion=1,
+        )
+        tr_hbox.AddSpacer(5)
+        ##################################################
+        # Amplitude controls
+        ##################################################
+        amp_hbox = forms.static_box_sizer(parent=self.panel, label="Amplitude", orient=wx.VERTICAL, bold=True)
+        amp_hbox.AddSpacer(5)
+        # First row of amp controls (ampl)
+        lvl_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        amp_hbox.Add(lvl_hbox, 0, wx.EXPAND)
+        amp_hbox.AddSpacer(10)
+        # Second row of amp controls (tx gain)
+        gain_hbox = wx.BoxSizer(wx.HORIZONTAL)
+        amp_hbox.Add(gain_hbox, 0, wx.EXPAND)
+        amp_hbox.AddSpacer(5)
+        self.vbox.Add(amp_hbox, 0, wx.EXPAND)
+        self.vbox.AddSpacer(10)
+        self.vbox.AddStretchSpacer()
+        lvl_hbox.AddSpacer(5)
+        forms.text_box(
+            parent=self.panel, sizer=lvl_hbox,
+            proportion=1,
+            converter=forms.float_converter(),
+            ps=self.tb,
+            key=usrp_siggen.AMPLITUDE_KEY,
+            label="Level (0.0-1.0)",
+        )
+        lvl_hbox.AddSpacer(10)
+        forms.log_slider(
+            parent=self.panel, sizer=lvl_hbox,
+            proportion=2,
+            ps=self.tb,
+            key=usrp_siggen.AMPLITUDE_KEY,
+            min_exp=-6,
+            max_exp=0,
+            base=10,
+            num_steps=100,
+        )
+        lvl_hbox.AddSpacer(5)
+        if self.tb[usrp_siggen.GAIN_RANGE_KEY][0] < self.tb[usrp_siggen.GAIN_RANGE_KEY][1]:
+            gain_hbox.AddSpacer(5)
+            forms.text_box(
+                parent=self.panel, sizer=gain_hbox,
+                proportion=1,
+                converter=forms.float_converter(),
+                ps=self.tb,
+                key=usrp_siggen.GAIN_KEY,
+                label="TX Gain (dB)",
+            )
+            gain_hbox.AddSpacer(10)
+            forms.slider(
+                parent=self.panel, sizer=gain_hbox,
+                proportion=2,
+                ps=self.tb,
+                key=usrp_siggen.GAIN_KEY,
+                minimum=self.tb[usrp_siggen.GAIN_RANGE_KEY][0],
+                maximum=self.tb[usrp_siggen.GAIN_RANGE_KEY][1],
+                step_size=self.tb[usrp_siggen.GAIN_RANGE_KEY][2],
+            )
+            gain_hbox.AddSpacer(5)
+        ##################################################
+        # Sample Rate controls
+        ##################################################
+        sam_hbox = forms.static_box_sizer(parent=self.panel, label="Sample Rate", orient=wx.HORIZONTAL, bold=True)
+        self.vbox.Add(sam_hbox, 0, wx.EXPAND)
+        self.vbox.AddSpacer(10)
+        self.vbox.AddStretchSpacer()
+        sam_hbox.AddSpacer(5)
+        forms.text_box(
+            parent=self.panel, sizer=sam_hbox,
+            converter=forms.int_converter(),
+            ps=self.tb,
+            key=usrp_siggen.INTERP_KEY,
+            label="Interpolation",
+        )
+        sam_hbox.AddStretchSpacer(20)
+        forms.static_text(
+            parent=self.panel, sizer=sam_hbox,
+            label='Sample Rate (sps)',
+            ps=self.tb,
+            key=usrp_siggen.SAMP_RATE_KEY,
+            converter=forms.float_converter(),
+        )
+        sam_hbox.AddStretchSpacer(20)
+        forms.static_text(
+            parent=self.panel, sizer=sam_hbox,
+            label='Link Rate (bits/sec)',
+            ps=self.tb,
+            key=usrp_siggen.LINK_RATE_KEY,
+            converter=forms.float_converter(),
+        )
+        sam_hbox.AddSpacer(5)
+        ##################################################
+        # USRP status
+        ##################################################
+        u2_hbox = forms.static_box_sizer(parent=self.panel, label="USRP Status", orient=wx.HORIZONTAL, bold=True)
+        self.vbox.Add(u2_hbox, 0, wx.EXPAND)
+        self.vbox.AddSpacer(10)
+        self.vbox.AddStretchSpacer()
+        u2_hbox.AddSpacer(10)
+        forms.static_text(
+            parent=self.panel, sizer=u2_hbox,
+            ps=self.tb,
+            key=usrp_siggen.DESC_KEY,
+            converter=forms.str_converter(),
+        )
+        self.vbox.AddSpacer(5)
+        self.vbox.AddStretchSpacer()
+
+if __name__ == "__main__":
+    try:
+        # Get command line parameters
+        (options, args) = usrp_siggen.get_options()
+
+        # Create the top block using these
+        tb = usrp_siggen.top_block(options, args)
+
+        # Create the GUI application
+        app = gui.app(top_block=tb,                    # Constructed top block
+                      gui=app_gui,                     # User interface class
+                      options=options,                 # Command line options
+                      args=args,                       # Command line args
+                      title="USRP Signal Generator",  # Top window title
+                      nstatus=1,                       # Number of status lines
+                      start=True,                      # Whether to start flowgraph
+                      realtime=True)                   # Whether to set realtime priority
+
+        # And run it
+        app.MainLoop()
+
+    except RuntimeError, e:
+        print e
+        sys.exit(1)
index 9f757aa8410eb24b7d226e9c828da4caa8a2fd6c..3cc13466a5de900c8ecc751f8b4aa323e952f7b8 100644 (file)
@@ -134,8 +134,7 @@ class slider_converter(abstract_converter):
                self._scaler = float(maximum - minimum)/num_steps
                self._cast = cast
        def external_to_internal(self, v):
-               #slider's internal representation is an integer
-               return int(round((v - self._offset)/self._scaler))
+               return (v - self._offset)/self._scaler
        def internal_to_external(self, v):
                return self._cast(v*self._scaler + self._offset)
        def help(self):
index c69315b0358906c531bd1ceaeaeb23defe9237e1..8dc58367d9deac34251467061d307388b816945e 100644 (file)
@@ -176,7 +176,7 @@ class _slider_base(_form_base):
                self._add_widget(self._slider, label, flag=wx.EXPAND)
 
        def _handle(self, event): self[INT_KEY] = self._slider.GetValue()
-       def _update(self, value): self._slider.SetValue(value)
+       def _update(self, value): self._slider.SetValue(int(round(value)))
 
 ########################################################################
 # Static Text Form
@@ -224,11 +224,18 @@ class text_box(_form_base):
        def __init__(self, label='', width=-1, converter=converters.eval_converter(), **kwargs):
                _form_base.__init__(self, converter=converter, **kwargs)
                self._text_box = wx.TextCtrl(self._parent, size=wx.Size(width, -1), style=wx.TE_PROCESS_ENTER)
+               self._default_bg_colour = self._text_box.GetBackgroundColour()
                self._text_box.Bind(wx.EVT_TEXT_ENTER, self._handle)
+               self._text_box.Bind(wx.EVT_TEXT, self._update_color)
                self._add_widget(self._text_box, label)
 
+       def _update_color(self, *args):
+               if self._text_box.GetValue() == self[INT_KEY]:
+                       self._text_box.SetBackgroundColour(self._default_bg_colour)
+               else: self._text_box.SetBackgroundColour('#EEDDDD')
+
        def _handle(self, event): self[INT_KEY] = self._text_box.GetValue()
-       def _update(self, value): self._text_box.SetValue(value)
+       def _update(self, value): self._text_box.SetValue(value); self._update_color()
 
 ########################################################################
 # Slider Form
index 89a768d4685c43bdde8e820017ffc185bf80257f..165e179d677f6f00f8f71d3285da72d240113daa 100644 (file)
@@ -2,3 +2,4 @@
 /Makefile.in
 /.libs
 /.deps
+test_gruel