From af5e21e35cda1d9d3e4bd659364dafe181274064 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Oct 2009 09:48:24 -0700 Subject: [PATCH] setup special wxgui connect on sinks, needs testing --- gr-wxgui/src/python/common.py | 25 ++++++++++++- gr-wxgui/src/python/constsink_gl.py | 6 +-- gr-wxgui/src/python/fftsink_gl.py | 5 +-- gr-wxgui/src/python/histosink_gl.py | 6 +-- gr-wxgui/src/python/numbersink2.py | 6 +-- gr-wxgui/src/python/scopesink_gl.py | 49 +++++++++++++------------ gr-wxgui/src/python/waterfallsink_gl.py | 6 +-- 7 files changed, 63 insertions(+), 40 deletions(-) diff --git a/gr-wxgui/src/python/common.py b/gr-wxgui/src/python/common.py index fe080aa4..dca41c9a 100644 --- a/gr-wxgui/src/python/common.py +++ b/gr-wxgui/src/python/common.py @@ -19,6 +19,9 @@ # Boston, MA 02110-1301, USA. # +################################################## +# conditional disconnections of wx flow graph +################################################## import wx def bind_to_visible_event(win, callback): @@ -51,14 +54,14 @@ def bind_to_visible_event(win, callback): from gnuradio import gr -def special_connect(source, sink, hb, win, size): +def conditional_connect(source, sink, hb, win, size): nulls = list() cache = [None] def callback(visible, init=False): if visible == cache[0]: return cache[0] = visible if not init: hb.lock() - print 'visible', visible + print 'visible', visible, source, sink if visible: if not init: hb.disconnect(source, nulls[0]) @@ -75,6 +78,24 @@ def special_connect(source, sink, hb, win, size): callback(False, init=True) #initially connect bind_to_visible_event(win, callback) +class wxgui_hb(object): + 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. + """ + try: + assert points[0] == self or points[0][0] == self + conditional_connect( + points[0], points[1], + win=self.win, hb=self, + size=self._hb.input_signature().sizeof_stream_item(0), + ) + if len(points[1:]) > 1: self.connect(*points[1:]) + except (AssertionError, IndexError): self.connect(*points) + #A macro to apply an index to a key index_key = lambda key, i: "%s_%d"%(key, i+1) diff --git a/gr-wxgui/src/python/constsink_gl.py b/gr-wxgui/src/python/constsink_gl.py index b3a1625b..91bc65d9 100644 --- a/gr-wxgui/src/python/constsink_gl.py +++ b/gr-wxgui/src/python/constsink_gl.py @@ -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) diff --git a/gr-wxgui/src/python/fftsink_gl.py b/gr-wxgui/src/python/fftsink_gl.py index 4edb11b4..9d683d69 100644 --- a/gr-wxgui/src/python/fftsink_gl.py +++ b/gr-wxgui/src/python/fftsink_gl.py @@ -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. """ @@ -105,8 +105,7 @@ class _fft_sink_base(gr.hier_block2): 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 - common.special_connect(self, fft, hb=self, win=self.win, size=self._item_size) - self.connect(fft, sink) + self.wxgui_connect(self, fft, sink) class fft_sink_f(_fft_sink_base): _fft_chain = blks2.logpwrfft_f diff --git a/gr-wxgui/src/python/histosink_gl.py b/gr-wxgui/src/python/histosink_gl.py index db6606e4..509f746b 100644 --- a/gr-wxgui/src/python/histosink_gl.py +++ b/gr-wxgui/src/python/histosink_gl.py @@ -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 diff --git a/gr-wxgui/src/python/numbersink2.py b/gr-wxgui/src/python/numbersink2.py index 7f853e6a..011acdfd 100644 --- a/gr-wxgui/src/python/numbersink2.py +++ b/gr-wxgui/src/python/numbersink2.py @@ -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 diff --git a/gr-wxgui/src/python/scopesink_gl.py b/gr-wxgui/src/python/scopesink_gl.py index a5e3ca3c..2882488e 100644 --- a/gr-wxgui/src/python/scopesink_gl.py +++ b/gr-wxgui/src/python/scopesink_gl.py @@ -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 diff --git a/gr-wxgui/src/python/waterfallsink_gl.py b/gr-wxgui/src/python/waterfallsink_gl.py index 2d4c959f..37844399 100644 --- a/gr-wxgui/src/python/waterfallsink_gl.py +++ b/gr-wxgui/src/python/waterfallsink_gl.py @@ -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 -- 2.30.2