~ubuntu-branches/ubuntu/trusty/gnuradio/trusty-updates

« back to all changes in this revision

Viewing changes to gr-wxgui/src/python/common.py

  • Committer: Package Import Robot
  • Author(s): A. Maitland Bottoms
  • Date: 2012-02-26 21:26:16 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20120226212616-vsfkbi1158xshdql
Tags: 3.5.1-1
* new upstream version, re-packaged from scratch with modern tools
    closes: #642716, #645332, #394849, #616832, #590048, #642580,
    #647018, #557050, #559640, #631863
* CMake build

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#
2
 
# Copyright 2008 Free Software Foundation, Inc.
 
2
# Copyright 2008, 2009 Free Software Foundation, Inc.
3
3
#
4
4
# This file is part of GNU Radio
5
5
#
19
19
# Boston, MA 02110-1301, USA.
20
20
#
21
21
 
 
22
##################################################
 
23
# conditional disconnections of wx flow graph
 
24
##################################################
 
25
import wx
 
26
from gnuradio import gr
 
27
 
 
28
RUN_ALWAYS = gr.prefs().get_bool ('wxgui', 'run_always', False)
 
29
 
 
30
class wxgui_hb(object):
 
31
        """
 
32
        The wxgui hier block helper/wrapper class:
 
33
        A hier block should inherit from this class to make use of the wxgui connect method.
 
34
        To use, call wxgui_connect in place of regular connect; self.win must be defined.
 
35
        The implementation will conditionally enable the copy block after the source (self).
 
36
        This condition depends on weather or not the window is visible with the parent notebooks.
 
37
        This condition will be re-checked on every ui update event.
 
38
        """
 
39
 
 
40
        def wxgui_connect(self, *points):
 
41
                """
 
42
                Use wxgui connect when the first point is the self source of the hb.
 
43
                The win property of this object should be set to the wx window.
 
44
                When this method tries to connect self to the next point,
 
45
                it will conditionally make this connection based on the visibility state.
 
46
                All other points will be connected normally.
 
47
                """
 
48
                try:
 
49
                        assert points[0] == self or points[0][0] == self
 
50
                        copy = gr.copy(self._hb.input_signature().sizeof_stream_item(0))
 
51
                        handler = self._handler_factory(copy.set_enabled)
 
52
                        if RUN_ALWAYS == False:
 
53
                                handler(False) #initially disable the copy block
 
54
                        else:
 
55
                                handler(True) #initially enable the copy block
 
56
                        self._bind_to_visible_event(win=self.win, handler=handler)
 
57
                        points = list(points)
 
58
                        points.insert(1, copy) #insert the copy block into the chain
 
59
                except (AssertionError, IndexError): pass
 
60
                self.connect(*points) #actually connect the blocks
 
61
 
 
62
        @staticmethod
 
63
        def _handler_factory(handler):
 
64
                """
 
65
                Create a function that will cache the visibility flag,
 
66
                and only call the handler when that flag changes.
 
67
                @param handler the function to call on a change
 
68
                @return a function of 1 argument
 
69
                """
 
70
                cache = [None]
 
71
                def callback(visible):
 
72
                        if cache[0] == visible: return
 
73
                        cache[0] = visible
 
74
                        #print visible, handler
 
75
                        if RUN_ALWAYS == False:
 
76
                                handler(visible)
 
77
                        else:
 
78
                                handler(True)
 
79
                return callback
 
80
 
 
81
        @staticmethod
 
82
        def _bind_to_visible_event(win, handler):
 
83
                """
 
84
                Bind a handler to a window when its visibility changes.
 
85
                Specifically, call the handler when the window visibility changes.
 
86
                This condition is checked on every update ui event.
 
87
                @param win the wx window
 
88
                @param handler a function of 1 param
 
89
                """
 
90
                #is the window visible in the hierarchy
 
91
                def is_wx_window_visible(my_win):
 
92
                        while True:
 
93
                                parent = my_win.GetParent()
 
94
                                if not parent: return True #reached the top of the hierarchy
 
95
                                #if we are hidden, then finish, otherwise keep traversing up
 
96
                                if isinstance(parent, wx.Notebook) and parent.GetCurrentPage() != my_win: return False
 
97
                                my_win = parent
 
98
                #call the handler, the arg is shown or not
 
99
                def handler_factory(my_win, my_handler):
 
100
                        def callback(evt):
 
101
                                my_handler(is_wx_window_visible(my_win))
 
102
                                evt.Skip() #skip so all bound handlers are called
 
103
                        return callback
 
104
                handler = handler_factory(win, handler)
 
105
                #bind the handler to all the parent notebooks
 
106
                win.Bind(wx.EVT_UPDATE_UI, handler)
 
107
 
 
108
##################################################
 
109
# Helpful Functions
 
110
##################################################
 
111
 
22
112
#A macro to apply an index to a key
23
113
index_key = lambda key, i: "%s_%d"%(key, i+1)
24
114
 
134
224
        @param samples the array of real values
135
225
        @return a tuple of min, max
136
226
        """
137
 
        scale_factor = 3
 
227
        factor = 2.0
138
228
        mean = numpy.average(samples)
139
 
        rms = numpy.max([scale_factor*((numpy.sum((samples-mean)**2)/len(samples))**.5), .1])
140
 
        min = mean - rms
141
 
        max = mean + rms
142
 
        return min, max
 
229
        std = numpy.std(samples)
 
230
        fft = numpy.abs(numpy.fft.fft(samples - mean))
 
231
        envelope = 2*numpy.max(fft)/len(samples)
 
232
        ampl = max(std, envelope) or 0.1
 
233
        return mean - factor*ampl, mean + factor*ampl
 
234
 
 
235
def get_min_max_fft(fft_samps):
 
236
        """
 
237
        Get the minimum and maximum bounds for an array of fft samples.
 
238
        @param samples the array of real values
 
239
        @return a tuple of min, max
 
240
        """
 
241
        #get the peak level (max of the samples)
 
242
        peak_level = numpy.max(fft_samps)
 
243
        #separate noise samples
 
244
        noise_samps = numpy.sort(fft_samps)[:len(fft_samps)/2]
 
245
        #get the noise floor
 
246
        noise_floor = numpy.average(noise_samps)
 
247
        #get the noise deviation
 
248
        noise_dev = numpy.std(noise_samps)
 
249
        #determine the maximum and minimum levels
 
250
        max_level = peak_level
 
251
        min_level = noise_floor - abs(2*noise_dev)
 
252
        return min_level, max_level