Merge branch 'wip/wxgui' of http://gnuradio.org/git/jblum
authorJohnathan Corgan <jcorgan@corganenterprises.com>
Fri, 9 Oct 2009 05:12:41 +0000 (22:12 -0700)
committerJohnathan Corgan <jcorgan@corganenterprises.com>
Fri, 9 Oct 2009 05:12:41 +0000 (22:12 -0700)
* 'wip/wxgui' of http://gnuradio.org/git/jblum:
  using gr copy in the wxgui connect, added gr copy to grc xml
  Added gr.copy(itemsize) block
  point label transpareny, horizontal offset, and toggle on/off capability
  simplify some params
  moved the wxgui connect helper functions into the wrapper class
  making use of update ui event
  setup special wxgui connect on sinks, needs testing
  working special connect for fftsink
  work on a special connect function that registers a callback
  added bind to visible event function to callback when visibility changes within tabs

21 files changed:
gnuradio-core/src/lib/general/Makefile.am
gnuradio-core/src/lib/general/general.i
gnuradio-core/src/lib/general/gr_copy.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_copy.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_copy.i [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/Makefile.am
gnuradio-core/src/python/gnuradio/gr/qa_copy.py [new file with mode: 0755]
gr-wxgui/src/python/common.py
gr-wxgui/src/python/constsink_gl.py
gr-wxgui/src/python/fftsink_gl.py
gr-wxgui/src/python/histosink_gl.py
gr-wxgui/src/python/numbersink2.py
gr-wxgui/src/python/plotter/common.py
gr-wxgui/src/python/plotter/grid_plotter_base.py
gr-wxgui/src/python/scopesink_gl.py
gr-wxgui/src/python/waterfallsink_gl.py
grc/blocks/Makefile.am
grc/blocks/block_tree.xml
grc/blocks/gr_copy.xml [new file with mode: 0644]
grc/blocks/gr_kludge_copy.xml
grc/blocks/gr_nop.xml

index 9b070b8651487d85be89d015e2facf39662821e4..cf6ff1e651ad89baf5ea3544e0bebfc57bf72ab2 100644 (file)
@@ -51,6 +51,7 @@ libgeneral_la_SOURCES =               \
        gr_complex_to_interleaved_short.cc \
        gr_complex_to_xxx.cc            \
        gr_conjugate_cc.cc              \
+       gr_copy.cc                      \
        gr_constellation_decoder_cb.cc  \
        gr_correlate_access_code_bb.cc  \
        gr_costas_loop_cc.cc            \
@@ -204,6 +205,7 @@ grinclude_HEADERS =                         \
        gr_complex_to_xxx.h             \
        gr_conjugate_cc.h               \
        gr_constellation_decoder_cb.h   \
+       gr_copy.h                       \
        gr_correlate_access_code_bb.h   \
        gr_costas_loop_cc.h             \
        gr_count_bits.h                 \
@@ -373,6 +375,7 @@ swiginclude_HEADERS =                       \
        gr_complex_to_xxx.i             \
        gr_conjugate_cc.i               \
        gr_constellation_decoder_cb.i   \
+       gr_copy.i                       \
        gr_correlate_access_code_bb.i   \
        gr_costas_loop_cc.i             \
        gr_cpfsk_bc.i                   \
index 0684e63a55f7ae56d05a04d13a5d5b8f00a3915f..e1161c8eb7e94f74337831fac9f306980f55fd4b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2005,2006,2007,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <gr_stretch_ff.h>
 #include <gr_wavelet_ff.h>
 #include <gr_wvps_ff.h>
-
+#include <gr_copy.h>
 %}
 
 %include "gr_nop.i"
 %include "gr_stretch_ff.i"
 %include "gr_wavelet_ff.i"
 %include "gr_wvps_ff.i"
+%include "gr_copy.i"
diff --git a/gnuradio-core/src/lib/general/gr_copy.cc b/gnuradio-core/src/lib/general/gr_copy.cc
new file mode 100644 (file)
index 0000000..c6564c2
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_copy.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_copy_sptr
+gr_make_copy(size_t itemsize)
+{
+  return gnuradio::get_initial_sptr(new gr_copy(itemsize));
+}
+
+gr_copy::gr_copy(size_t itemsize)
+  : gr_block ("copy",
+             gr_make_io_signature (1, 1, itemsize),
+             gr_make_io_signature (1, 1, itemsize)),
+    d_itemsize(itemsize),
+    d_enabled(true)
+{
+}
+
+bool
+gr_copy::check_topology(int ninputs, int noutputs)
+{
+  return ninputs == noutputs;
+}
+
+int
+gr_copy::general_work(int noutput_items,
+                     gr_vector_int &ninput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items)
+{
+  const uint8_t *in = (const uint8_t *) input_items[0];
+  uint8_t *out = (uint8_t *) output_items[0];
+
+  int n = std::min<int>(ninput_items[0], noutput_items);
+  int j = 0;
+
+  if (d_enabled) {
+    memcpy(out, in, n*d_itemsize);
+    j = n;
+  }
+
+  consume_each(n);
+  return j;
+}
diff --git a/gnuradio-core/src/lib/general/gr_copy.h b/gnuradio-core/src/lib/general/gr_copy.h
new file mode 100644 (file)
index 0000000..d99aef8
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+#ifndef INCLUDED_GR_COPY_H
+#define INCLUDED_GR_COPY_H
+
+#include <gr_block.h>
+
+class gr_copy;
+typedef boost::shared_ptr<gr_copy> gr_copy_sptr;
+
+gr_copy_sptr gr_make_copy(size_t itemsize);
+
+/*!
+ * \brief output[i] = input[i]
+ * \ingroup misc_blk
+ *
+ * When enabled (default), this block copies its input to its output.
+ * When disabled, this block drops its input on the floor.
+ *
+ */
+class gr_copy : public gr_block
+{
+  size_t               d_itemsize;
+  bool                 d_enabled;
+
+  friend gr_copy_sptr gr_make_copy(size_t itemsize);
+  gr_copy(size_t itemsize);
+
+ public:
+
+  bool check_topology(int ninputs, int noutputs);
+
+  void set_enabled(bool enable) { d_enabled = enable; }
+  bool enabled() const { return d_enabled;}
+
+  int general_work(int noutput_items,
+                  gr_vector_int &ninput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_copy.i b/gnuradio-core/src/lib/general/gr_copy.i
new file mode 100644 (file)
index 0000000..e260d8e
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,copy)
+
+gr_copy_sptr gr_make_copy(size_t itemsize);
+
+class gr_copy : public gr_block
+{
+ private:
+  gr_copy(size_t itemsize);
+
+public:
+
+  void set_enabled(bool enabled);
+  bool enabled();
+};
index 41ef52240968013c2ad75d16df6896977e4b696d..3aff89ee7852d60bbb695132f9ba2ac9f82e37bf 100644 (file)
@@ -54,6 +54,7 @@ noinst_PYTHON =                       \
        qa_cma_equalizer.py             \
        qa_complex_to_xxx.py            \
        qa_constellation_decoder_cb.py  \
+       qa_copy.py                      \
        qa_correlate_access_code.py     \
        qa_delay.py                     \
        qa_diff_encoder.py              \
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_copy.py b/gnuradio-core/src/python/gnuradio/gr/qa_copy.py
new file mode 100755 (executable)
index 0000000..7f9f72a
--- /dev/null
@@ -0,0 +1,58 @@
+#!/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.
+# 
+
+from gnuradio import gr, gr_unittest
+
+class test_copy(gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def test_copy (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+        expected_result = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+        src = gr.vector_source_b(src_data)
+        op = gr.copy(gr.sizeof_char)
+        dst = gr.vector_sink_b()
+        self.tb.connect(src, op, dst)
+        self.tb.run()
+        dst_data = dst.data()
+        self.assertEqual(expected_result, dst_data)
+    
+    def test_copy_drop (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+        expected_result = ()
+        src = gr.vector_source_b(src_data)
+        op = gr.copy(gr.sizeof_char)
+       op.set_enabled(False)
+        dst = gr.vector_sink_b()
+        self.tb.connect(src, op, dst)
+        self.tb.run()
+        dst_data = dst.data()
+        self.assertEqual(expected_result, dst_data)
+    
+
+if __name__ == '__main__':
+    gr_unittest.main ()
index 9c97ce1ecad898a32e1871f9445c42713db7fd9e..fa11b3152fd358bc005226697faebe6857d05fbd 100644 (file)
 # Boston, MA 02110-1301, USA.
 #
 
+##################################################
+# conditional disconnections of wx flow graph
+##################################################
+import wx
+from gnuradio import gr
+
+class wxgui_hb(object):
+       """
+       The wxgui hier block helper/wrapper class:
+       A hier block should inherit from this class to make use of the wxgui connect method.
+       To use, call wxgui_connect in place of regular connect; self.win must be defined.
+       The implementation will conditionally enable the copy block after the source (self).
+       This condition depends on weather or not the window is visible with the parent notebooks.
+       This condition will be re-checked on every ui update event.
+       """
+
+       def wxgui_connect(self, *points):
+               """
+               Use wxgui connect when the first point is the self source of the hb.
+               The win property of this object should be set to the wx window.
+               When this method tries to connect self to the next point,
+               it will conditionally make this connection based on the visibility state.
+               All other points will be connected normally.
+               """
+               try:
+                       assert points[0] == self or points[0][0] == self
+                       copy = gr.copy(self._hb.input_signature().sizeof_stream_item(0))
+                       handler = self._handler_factory(copy.set_enabled)
+                       handler(False) #initially disable the copy block
+                       self._bind_to_visible_event(win=self.win, handler=handler)
+                       points = list(points)
+                       points.insert(1, copy) #insert the copy block into the chain
+               except (AssertionError, IndexError): pass
+               self.connect(*points) #actually connect the blocks
+
+       @staticmethod
+       def _handler_factory(handler):
+               """
+               Create a function that will cache the visibility flag,
+               and only call the handler when that flag changes.
+               @param handler the function to call on a change
+               @return a function of 1 argument
+               """
+               cache = [None]
+               def callback(visible):
+                       if cache[0] == visible: return
+                       cache[0] = visible
+                       #print visible, handler
+                       handler(visible)
+               return callback
+
+       @staticmethod
+       def _bind_to_visible_event(win, handler):
+               """
+               Bind a handler to a window when its visibility changes.
+               Specifically, call the handler when the window visibility changes.
+               This condition is checked on every update ui event.
+               @param win the wx window
+               @param handler a function of 1 param
+               """
+               #is the window visible in the hierarchy
+               def is_wx_window_visible(my_win):
+                       while True:
+                               parent = my_win.GetParent()
+                               if not parent: return True #reached the top of the hierarchy
+                               #if we are hidden, then finish, otherwise keep traversing up
+                               if isinstance(parent, wx.Notebook) and parent.GetCurrentPage() != my_win: return False
+                               my_win = parent
+               #call the handler, the arg is shown or not
+               def handler_factory(my_win, my_handler):
+                       return lambda *args: my_handler(is_wx_window_visible(my_win))
+               handler = handler_factory(win, handler)
+               #bind the handler to all the parent notebooks
+               win.Bind(wx.EVT_UPDATE_UI, handler)
+
+##################################################
+# Helpful Functions
+##################################################
+
 #A macro to apply an index to a key
 index_key = lambda key, i: "%s_%d"%(key, i+1)
 
index b3a1625b09b5ab412ce3f239c285d4c2c58a91ad..91bc65d9fb6a3142492b44a4cdc8cc553072e3dc 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # Constellation sink block (wrapper for old wxgui)
 ##################################################
-class const_sink_c(gr.hier_block2):
+class const_sink_c(gr.hier_block2, common.wxgui_hb):
        """
        A constellation block with a gui window.
        """
@@ -94,8 +94,6 @@ class const_sink_c(gr.hier_block2):
                agc = gr.feedforward_agc_cc(16, 1)
                msgq = gr.msg_queue(2)
                sink = gr.message_sink(gr.sizeof_gr_complex*const_size, msgq, True)
-               #connect
-               self.connect(self, self._costas, self._retime, agc, sd, sink)
                #controller
                def setter(p, k, x): p[k] = x
                self.controller = pubsub()
@@ -131,5 +129,7 @@ class const_sink_c(gr.hier_block2):
                        sample_rate_key=SAMPLE_RATE_KEY,
                )
                common.register_access_methods(self, self.win)
+               #connect
+               self.wxgui_connect(self, self._costas, self._retime, agc, sd, sink)
 
 
index 3f0a93fc8b3056fa34771ae998d17746d04a919e..9d683d69795c3cf7f7fe320a5fb5dd262a215347 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # FFT sink block (wrapper for old wxgui)
 ##################################################
-class _fft_sink_base(gr.hier_block2):
+class _fft_sink_base(gr.hier_block2, common.wxgui_hb):
        """
        An fft block with real/complex inputs and a gui window.
        """
@@ -73,8 +73,6 @@ class _fft_sink_base(gr.hier_block2):
                )
                msgq = gr.msg_queue(2)
                sink = gr.message_sink(gr.sizeof_float*fft_size, msgq, True)
-               #connect
-               self.connect(self, fft, sink)
                #controller
                self.controller = pubsub()
                self.controller.subscribe(AVERAGE_KEY, fft.set_average)
@@ -106,6 +104,8 @@ class _fft_sink_base(gr.hier_block2):
                common.register_access_methods(self, self.win)
                setattr(self.win, 'set_baseband_freq', getattr(self, 'set_baseband_freq')) #BACKWARDS
                setattr(self.win, 'set_peak_hold', getattr(self, 'set_peak_hold')) #BACKWARDS
+               #connect
+               self.wxgui_connect(self, fft, sink)
 
 class fft_sink_f(_fft_sink_base):
        _fft_chain = blks2.logpwrfft_f
index db6606e413c14cbd94274bba1e8c572997f22b42..509f746be68a9e763c0d6c6f6ac83e073546d39d 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # histo sink block (wrapper for old wxgui)
 ##################################################
-class histo_sink_f(gr.hier_block2):
+class histo_sink_f(gr.hier_block2, common.wxgui_hb):
        """
        A histogram block and a gui window.
        """
@@ -56,8 +56,6 @@ class histo_sink_f(gr.hier_block2):
                histo = gr.histo_sink_f(msgq)
                histo.set_num_bins(num_bins)
                histo.set_frame_size(frame_size)
-               #connect
-               self.connect(self, histo)
                #controller
                self.controller = pubsub()
                self.controller.subscribe(NUM_BINS_KEY, histo.set_num_bins)
@@ -79,6 +77,8 @@ class histo_sink_f(gr.hier_block2):
                        msg_key=MSG_KEY,
                )
                common.register_access_methods(self, self.win)
+               #connect
+               self.wxgui_connect(self, histo)
 
 # ----------------------------------------------------------------
 # Standalone test app
index 7f853e6a4f3f7b73b2acda44b0d8d1f0d87d5c3b..011acdfd5e93e01b8c7907c9d264b40e5bcd7f66 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # Number sink block (wrapper for old wxgui)
 ##################################################
-class _number_sink_base(gr.hier_block2):
+class _number_sink_base(gr.hier_block2, common.wxgui_hb):
        """
        An decimator block with a number window display
        """
@@ -81,8 +81,6 @@ class _number_sink_base(gr.hier_block2):
                        avg = gr.single_pole_iir_filter_cc(1.0)
                msgq = gr.msg_queue(2)
                sink = gr.message_sink(self._item_size, msgq, True)
-               #connect
-               self.connect(self, sd, mult, add, avg, sink)
                #controller
                self.controller = pubsub()
                self.controller.subscribe(SAMPLE_RATE_KEY, sd.set_sample_rate)
@@ -118,6 +116,8 @@ class _number_sink_base(gr.hier_block2):
                common.register_access_methods(self, self.controller)
                #backwards compadibility
                self.set_show_gauge = self.win.show_gauges
+               #connect
+               self.wxgui_connect(self, sd, mult, add, avg, sink)
 
 class number_sink_f(_number_sink_base):
        _item_size = gr.sizeof_float
index 7699986aad1e65d61c8637980d323c8702771bc9..4c50cd7872e1750cf61180eb651dd1661e02d85e 100644 (file)
@@ -102,6 +102,7 @@ class point_label_thread(threading.Thread, mutex):
                #bind plotter mouse events
                self._plotter.Bind(wx.EVT_MOTION, lambda evt: self.enqueue(evt.GetPosition()))
                self._plotter.Bind(wx.EVT_LEAVE_WINDOW, lambda evt: self.enqueue(None))
+               self._plotter.Bind(wx.EVT_RIGHT_DOWN, lambda evt: plotter.enable_point_label(not plotter.enable_point_label()))
                #start the thread
                threading.Thread.__init__(self)
                self.start()
index 39bed181111140abb52b9ca01ddfd134cacc8726..a9bd02731479ac3be8780eb8631a3792a7316772 100644 (file)
@@ -36,8 +36,9 @@ AXIS_LABEL_PADDING = 5
 TICK_LABEL_PADDING = 5
 TITLE_LABEL_PADDING = 7
 POINT_LABEL_FONT_SIZE = 8
-POINT_LABEL_COLOR_SPEC = (1, 1, .5)
+POINT_LABEL_COLOR_SPEC = (1, 1, 0.5, 0.75)
 POINT_LABEL_PADDING = 3
+POINT_LABEL_OFFSET = 10
 GRID_LINE_DASH_LEN = 4
 
 ##################################################
@@ -395,8 +396,12 @@ class grid_plotter_base(plotter_base):
                if not label_str: return
                txt = gltext.Text(label_str, font_size=POINT_LABEL_FONT_SIZE)
                w, h = txt.get_size()
+               #enable transparency
+               GL.glEnable(GL.GL_BLEND)
+               GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
                #draw rect + text
-               GL.glColor3f(*POINT_LABEL_COLOR_SPEC)
-               if x > self.width/2: x -= w+2*POINT_LABEL_PADDING
+               GL.glColor4f(*POINT_LABEL_COLOR_SPEC)
+               if x > self.width/2: x -= w+2*POINT_LABEL_PADDING + POINT_LABEL_OFFSET
+               else: x += POINT_LABEL_OFFSET
                self._draw_rect(x, y-h-2*POINT_LABEL_PADDING, w+2*POINT_LABEL_PADDING, h+2*POINT_LABEL_PADDING)
                txt.draw_text(wx.Point(x+POINT_LABEL_PADDING, y-h-POINT_LABEL_PADDING))
index a5e3ca3ce32fc7f9c40fd305d5c7fd4bd2d709e5..2882488e3dabcfa341c2eaf165b0b0d3a32bd888 100644 (file)
@@ -34,7 +34,7 @@ class ac_couple_block(gr.hier_block2):
        Mute the low pass filter to disable ac coupling.
        """
 
-       def __init__(self, controller, ac_couple_key, ac_couple, sample_rate_key):
+       def __init__(self, controller, ac_couple_key, sample_rate_key):
                gr.hier_block2.__init__(
                        self,
                        "ac_couple",
@@ -52,13 +52,13 @@ class ac_couple_block(gr.hier_block2):
                controller.subscribe(ac_couple_key, lambda x: mute.set_mute(not x))
                controller.subscribe(sample_rate_key, lambda x: lpf.set_taps(0.05))
                #initialize
-               controller[ac_couple_key] = ac_couple
+               controller[ac_couple_key] = controller[ac_couple_key]
                controller[sample_rate_key] = controller[sample_rate_key]
 
 ##################################################
 # Scope sink block (wrapper for old wxgui)
 ##################################################
-class _scope_sink_base(gr.hier_block2):
+class _scope_sink_base(gr.hier_block2, common.wxgui_hb):
        """
        A scope block with a gui window.
        """
@@ -102,25 +102,10 @@ class _scope_sink_base(gr.hier_block2):
                self.controller.publish(TRIGGER_SLOPE_KEY, scope.get_trigger_slope)
                self.controller.subscribe(TRIGGER_CHANNEL_KEY, scope.set_trigger_channel)
                self.controller.publish(TRIGGER_CHANNEL_KEY, scope.get_trigger_channel)
-               #connect
-               if self._real:
-                       for i in range(num_inputs):
-                               self.connect(
-                                       (self, i),
-                                       ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, i), ac_couple, SAMPLE_RATE_KEY),
-                                       (scope, i),
-                               )
-               else:
-                       for i in range(num_inputs):
-                               c2f = gr.complex_to_float() 
-                               self.connect((self, i), c2f)
-                               for j in range(2):
-                                       self.connect(
-                                               (c2f, j), 
-                                               ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, 2*i+j), ac_couple, SAMPLE_RATE_KEY),
-                                               (scope, 2*i+j),
-                                       )
-                       num_inputs *= 2
+               actual_num_inputs = self._real and num_inputs or num_inputs*2
+               #init ac couple
+               for i in range(actual_num_inputs):
+                       self.controller[common.index_key(AC_COUPLE_KEY, i)] = ac_couple
                #start input watcher
                common.input_watcher(msgq, self.controller, MSG_KEY)
                #create window
@@ -130,7 +115,7 @@ class _scope_sink_base(gr.hier_block2):
                        size=size,
                        title=title,
                        frame_rate=frame_rate,
-                       num_inputs=num_inputs,
+                       num_inputs=actual_num_inputs,
                        sample_rate_key=SAMPLE_RATE_KEY,
                        t_scale=t_scale,
                        v_scale=v_scale,
@@ -144,6 +129,24 @@ class _scope_sink_base(gr.hier_block2):
                        msg_key=MSG_KEY,
                )
                common.register_access_methods(self, self.win)
+               #connect
+               if self._real:
+                       for i in range(num_inputs):
+                               self.wxgui_connect(
+                                       (self, i),
+                                       ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, i), SAMPLE_RATE_KEY),
+                                       (scope, i),
+                               )
+               else:
+                       for i in range(num_inputs):
+                               c2f = gr.complex_to_float() 
+                               self.wxgui_connect((self, i), c2f)
+                               for j in range(2):
+                                       self.connect(
+                                               (c2f, j), 
+                                               ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, 2*i+j), SAMPLE_RATE_KEY),
+                                               (scope, 2*i+j),
+                                       )
 
 class scope_sink_f(_scope_sink_base):
        _item_size = gr.sizeof_float
index 2d4c959f8a8f14baafb64409092c807513409ac4..37844399ed6337e1a9fdf992c3dc0b63b2b98b1c 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # Waterfall sink block (wrapper for old wxgui)
 ##################################################
-class _waterfall_sink_base(gr.hier_block2):
+class _waterfall_sink_base(gr.hier_block2, common.wxgui_hb):
        """
        An fft block with real/complex inputs and a gui window.
        """
@@ -73,8 +73,6 @@ class _waterfall_sink_base(gr.hier_block2):
                )
                msgq = gr.msg_queue(2)
                sink = gr.message_sink(gr.sizeof_float*fft_size, msgq, True)
-               #connect
-               self.connect(self, fft, sink)
                #controller
                self.controller = pubsub()
                self.controller.subscribe(AVERAGE_KEY, fft.set_average)
@@ -110,6 +108,8 @@ class _waterfall_sink_base(gr.hier_block2):
                )
                common.register_access_methods(self, self.win)
                setattr(self.win, 'set_baseband_freq', getattr(self, 'set_baseband_freq')) #BACKWARDS
+               #connect
+               self.wxgui_connect(self, fft, sink)
 
 class waterfall_sink_f(_waterfall_sink_base):
        _fft_chain = blks2.logpwrfft_f
index 617a3bf6085bd50f2f1b577d1c7fc404dd1fbe2d..df3479761a32d137d7e0267b5b42bc769ad1cb1b 100644 (file)
@@ -84,6 +84,7 @@ dist_ourdata_DATA = \
        gr_complex_to_real.xml \
        gr_conjugate_cc.xml \
        gr_constellation_decoder_cb.xml \
+       gr_copy.xml \
        gr_correlate_access_code_bb.xml \
        gr_costas_loop_cc.xml \
        gr_cpfsk_bc.xml \
index 296f0ee911b505298cc893675656aa1cd88f74e1..6fec0be675871d9cbe4cc263100b289ee5107fca 100644 (file)
                <block>gr_skiphead</block>
 
                <block>gr_kludge_copy</block>
+               <block>gr_copy</block>
                <block>gr_nop</block>
 
                <block>xmlrpc_server</block>
diff --git a/grc/blocks/gr_copy.xml b/grc/blocks/gr_copy.xml
new file mode 100644 (file)
index 0000000..757f143
--- /dev/null
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Copy
+###################################################
+ -->
+<block>
+       <name>Copy</name>
+       <key>gr_copy</key>
+       <import>from gnuradio import gr</import>
+       <make>gr.copy($type.size*$vlen)
+self.$(id).set_enabled($enabled)</make>
+       <callback>set_enabled($enabled)</callback>
+       <param>
+               <name>Type</name>
+               <key>type</key>
+               <type>enum</type>
+               <option>
+                       <name>Complex</name>
+                       <key>complex</key>
+                       <opt>size:gr.sizeof_gr_complex</opt>
+               </option>
+               <option>
+                       <name>Float</name>
+                       <key>float</key>
+                       <opt>size:gr.sizeof_float</opt>
+               </option>
+               <option>
+                       <name>Int</name>
+                       <key>int</key>
+                       <opt>size:gr.sizeof_int</opt>
+               </option>
+               <option>
+                       <name>Short</name>
+                       <key>short</key>
+                       <opt>size:gr.sizeof_short</opt>
+               </option>
+               <option>
+                       <name>Byte</name>
+                       <key>byte</key>
+                       <opt>size:gr.sizeof_char</opt>
+               </option>
+       </param>
+       <param>
+               <name>Enabled</name>
+               <key>enabled</key>
+               <value>True</value>
+               <type>bool</type>
+       </param>
+       <param>
+               <name>Vec Length</name>
+               <key>vlen</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
+       <check>$vlen &gt; 0</check>
+       <sink>
+               <name>in</name>
+               <type>$type</type>
+               <vlen>$vlen</vlen>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>$type</type>
+               <vlen>$vlen</vlen>
+       </source>
+</block>
index 3c817c5726709402a6fe48152f7ab1864f6d2145..8058b082dbd370fa540a0cbe9f8dfb77e7b5a738 100644 (file)
@@ -5,7 +5,7 @@
 ###################################################
  -->
 <block>
-       <name>Copy</name>
+       <name>Kludge Copy</name>
        <key>gr_kludge_copy</key>
        <import>from gnuradio import gr</import>
        <make>gr.kludge_copy($type.size*$vlen)</make>
                        <opt>size:gr.sizeof_char</opt>
                </option>
        </param>
+       <param>
+               <name>Num Ports</name>
+               <key>num_ports</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
        <param>
                <name>Vec Length</name>
                <key>vlen</key>
                <value>1</value>
                <type>int</type>
        </param>
+       <check>$num_ports &gt; 0</check>
        <check>$vlen &gt; 0</check>
        <sink>
                <name>in</name>
                <type>$type</type>
                <vlen>$vlen</vlen>
+               <nports>$num_ports</nports>
        </sink>
        <source>
                <name>out</name>
                <type>$type</type>
                <vlen>$vlen</vlen>
+               <nports>$num_ports</nports>
        </source>
 </block>
index 127a78a55364cfbc739fcc74ac6856e5acfeed22..bd884d6b8bff7f22f95d83c1a0361c4cd470ea15 100644 (file)
                        <opt>size:gr.sizeof_char</opt>
                </option>
        </param>
+       <param>
+               <name>Num Ports</name>
+               <key>num_ports</key>
+               <value>1</value>
+               <type>int</type>
+       </param>
        <param>
                <name>Vec Length</name>
                <key>vlen</key>
                <value>1</value>
                <type>int</type>
        </param>
+       <check>$num_ports &gt; 0</check>
        <check>$vlen &gt; 0</check>
        <sink>
                <name>in</name>
                <type>$type</type>
                <vlen>$vlen</vlen>
+               <nports>$num_ports</nports>
        </sink>
        <source>
                <name>out</name>
                <type>$type</type>
                <vlen>$vlen</vlen>
+               <nports>$num_ports</nports>
        </source>
 </block>