gr-wxgui: update copyrights
[debian/gnuradio] / gr-wxgui / src / python / fftsink_nongl.py
index f4e9143f1d17709edcbe7457eb34efa25c9dfde3..508b4e772f5b8f1ae741e1193ca6ee2048589710 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2003,2004,2005,2006,2007 Free Software Foundation, Inc.
+# Copyright 2003,2004,2005,2006,2007,2009,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -25,7 +25,6 @@ from gnuradio.wxgui import stdgui2
 import wx
 import plot
 import numpy
-import threading
 import math    
 
 DIV_LEVELS = (1, 2, 5, 10, 20)
@@ -38,7 +37,7 @@ class fft_sink_base(object):
                  y_divs=8, ref_level=50,
                  sample_rate=1, fft_size=512,
                  fft_rate=default_fft_rate,
-                 average=False, avg_alpha=None, title='', peak_hold=False):
+                 average=False, avg_alpha=None, title='', peak_hold=False,use_persistence=False,persist_alpha=0.2):
 
         # initialize common attributes
         self.baseband_freq = baseband_freq
@@ -53,6 +52,9 @@ class fft_sink_base(object):
             self.avg_alpha = 2.0 / fft_rate
         else:
             self.avg_alpha = avg_alpha
+        self.use_persistence = use_persistence
+        self.persist_alpha = persist_alpha
+
         self.title = title
         self.peak_hold = peak_hold
         self.input_is_real = input_is_real
@@ -76,6 +78,14 @@ class fft_sink_base(object):
         self.peak_hold = enable
         self.win.set_peak_hold(enable)
 
+    def set_use_persistence(self, enable):
+        self.use_persistence = enable
+        self.win.set_use_persistence(enable)
+
+    def set_persist_alpha(self, persist_alpha):
+        self.persist_alpha = persist_alpha
+        self.win.set_persist_alpha(persist_alpha)
+
     def set_avg_alpha(self, avg_alpha):
         self.avg_alpha = avg_alpha
 
@@ -94,7 +104,7 @@ class fft_sink_f(gr.hier_block2, fft_sink_base):
     def __init__(self, parent, baseband_freq=0, ref_scale=2.0,
                  y_per_div=10, y_divs=8, ref_level=50, sample_rate=1, fft_size=512,
                  fft_rate=default_fft_rate, average=False, avg_alpha=None,
-                 title='', size=default_fftsink_size, peak_hold=False):
+                 title='', size=default_fftsink_size, peak_hold=False, use_persistence=False,persist_alpha=0.2, **kwargs):
 
         gr.hier_block2.__init__(self, "fft_sink_f",
                                 gr.io_signature(1, 1, gr.sizeof_float),
@@ -105,7 +115,7 @@ class fft_sink_f(gr.hier_block2, fft_sink_base):
                                sample_rate=sample_rate, fft_size=fft_size,
                                fft_rate=fft_rate,
                                average=average, avg_alpha=avg_alpha, title=title,
-                               peak_hold=peak_hold)
+                               peak_hold=peak_hold,use_persistence=use_persistence,persist_alpha=persist_alpha)
                                
         self.s2p = gr.stream_to_vector(gr.sizeof_float, self.fft_size)
         self.one_in_n = gr.keep_one_in_n(gr.sizeof_float * self.fft_size,
@@ -132,12 +142,14 @@ class fft_sink_f(gr.hier_block2, fft_sink_base):
         self.win = fft_window(self, parent, size=size)
         self.set_average(self.average)
         self.set_peak_hold(self.peak_hold)
+        self.set_use_persistence(self.use_persistence)
+        self.set_persist_alpha(self.persist_alpha)
 
 class fft_sink_c(gr.hier_block2, fft_sink_base):
     def __init__(self, parent, baseband_freq=0, ref_scale=2.0,
                  y_per_div=10, y_divs=8, ref_level=50, sample_rate=1, fft_size=512,
                  fft_rate=default_fft_rate, average=False, avg_alpha=None,
-                 title='', size=default_fftsink_size, peak_hold=False):
+                 title='', size=default_fftsink_size, peak_hold=False, use_persistence=False,persist_alpha=0.2, **kwargs):
 
         gr.hier_block2.__init__(self, "fft_sink_c",
                                 gr.io_signature(1, 1, gr.sizeof_gr_complex),
@@ -148,7 +160,7 @@ class fft_sink_c(gr.hier_block2, fft_sink_base):
                                sample_rate=sample_rate, fft_size=fft_size,
                                fft_rate=fft_rate,
                                average=average, avg_alpha=avg_alpha, title=title,
-                               peak_hold=peak_hold)
+                               peak_hold=peak_hold, use_persistence=use_persistence,persist_alpha=persist_alpha)
 
         self.s2p = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size)
         self.one_in_n = gr.keep_one_in_n(gr.sizeof_gr_complex * self.fft_size,
@@ -174,6 +186,8 @@ class fft_sink_c(gr.hier_block2, fft_sink_base):
 
         self.win = fft_window(self, parent, size=size)
         self.set_average(self.average)
+        self.set_use_persistence(self.use_persistence)
+        self.set_persist_alpha(self.persist_alpha)
         self.set_peak_hold(self.peak_hold)
 
 
@@ -193,34 +207,28 @@ class DataEvent(wx.PyEvent):
         self.__class__ (self.GetId())
 
 
-class input_watcher (threading.Thread):
+class input_watcher (gru.msgq_runner):
     def __init__ (self, msgq, fft_size, event_receiver, **kwds):
-        threading.Thread.__init__ (self, **kwds)
-        self.setDaemon (1)
-        self.msgq = msgq
         self.fft_size = fft_size
         self.event_receiver = event_receiver
-        self.keep_running = True
-        self.start ()
+        gru.msgq_runner.__init__(self, msgq, self.handle_msg)
 
-    def run (self):
-        while (self.keep_running):
-            msg = self.msgq.delete_head()  # blocking read of message queue
-            itemsize = int(msg.arg1())
-            nitems = int(msg.arg2())
+    def handle_msg(self, msg):
+        itemsize = int(msg.arg1())
+        nitems = int(msg.arg2())
 
-            s = msg.to_string()            # get the body of the msg as a string
+        s = msg.to_string() # get the body of the msg as a string
 
-            # There may be more than one FFT frame in the message.
-            # If so, we take only the last one
-            if nitems > 1:
-                start = itemsize * (nitems - 1)
-                s = s[start:start+itemsize]
+        # There may be more than one FFT frame in the message.
+        # If so, we take only the last one
+        if nitems > 1:
+            start = itemsize * (nitems - 1)
+            s = s[start:start+itemsize]
 
-            complex_data = numpy.fromstring (s, numpy.float32)
-            de = DataEvent (complex_data)
-            wx.PostEvent (self.event_receiver, de)
-            del de
+        complex_data = numpy.fromstring (s, numpy.float32)
+        de = DataEvent (complex_data)
+        wx.PostEvent (self.event_receiver, de)
+        del de
 
 class control_panel(wx.Panel):
     
@@ -243,6 +251,9 @@ class control_panel(wx.Panel):
         self.average_check_box = wx.CheckBox(parent=self, style=wx.CHK_2STATE, label="Average")
         self.average_check_box.Bind(wx.EVT_CHECKBOX, parent.on_average)
         control_box.Add(self.average_check_box, 0, wx.EXPAND)
+        self.use_persistence_check_box = wx.CheckBox(parent=self, style=wx.CHK_2STATE, label="Persistence")
+        self.use_persistence_check_box.Bind(wx.EVT_CHECKBOX, parent.on_use_persistence)
+        control_box.Add(self.use_persistence_check_box, 0, wx.EXPAND)
         self.peak_hold_check_box = wx.CheckBox(parent=self, style=wx.CHK_2STATE, label="Peak Hold")
         self.peak_hold_check_box.Bind(wx.EVT_CHECKBOX, parent.on_peak_hold) 
         control_box.Add(self.peak_hold_check_box, 0, wx.EXPAND)
@@ -278,11 +289,12 @@ class control_panel(wx.Panel):
         self.update()
         
     def update(self):
-        """!
+        """
         Read the state of the fft plot settings and update the control panel.
         """
         #update checkboxes
         self.average_check_box.SetValue(self.parent.fftsink.average)
+        self.use_persistence_check_box.SetValue(self.parent.fftsink.use_persistence)
         self.peak_hold_check_box.SetValue(self.parent.fftsink.peak_hold)
         #update radio buttons    
         try:
@@ -313,13 +325,17 @@ class fft_window (wx.Panel):
         
         self.peak_hold = False
         self.peak_vals = None
+
+        self.use_persistence=False
+        self.persist_alpha=0.2
+
         
         self.plot.SetEnableGrid (True)
         # self.SetEnableZoom (True)
         # self.SetBackgroundColour ('black')
         
         self.build_popup_menu()
-        self.set_baseband_freq(0.0)
+        self.set_baseband_freq(self.fftsink.baseband_freq)
                 
         EVT_DATA_EVENT (self, self.set_data)
         wx.EVT_CLOSE (self, self.on_close_window)
@@ -401,6 +417,14 @@ class fft_window (wx.Panel):
         y_range = ymin, ymax
         self.plot.Draw (graphics, xAxis=x_range, yAxis=y_range, step=self.fftsink.y_per_div)        
 
+    def set_use_persistence(self, enable):
+        self.use_persistence = enable
+        self.plot.set_use_persistence( enable)
+
+    def set_persist_alpha(self, persist_alpha):
+        self.persist_alpha = persist_alpha
+        self.plot.set_persist_alpha(persist_alpha)
+
     def set_peak_hold(self, enable):
         self.peak_hold = enable
         self.peak_vals = None
@@ -410,6 +434,11 @@ class fft_window (wx.Panel):
         self.fftsink.set_average(evt.IsChecked())
         self.control_panel.update()
 
+    def on_use_persistence(self, evt):
+        # print "on_analog"
+        self.fftsink.set_use_persistence(evt.IsChecked())
+        self.control_panel.update()
+
     def on_peak_hold(self, evt):
         # print "on_peak_hold"
         self.fftsink.set_peak_hold(evt.IsChecked())
@@ -493,9 +522,11 @@ class fft_window (wx.Panel):
         self.id_y_per_div_10 = wx.NewId()
         self.id_y_per_div_20 = wx.NewId()
         self.id_average = wx.NewId()
+        self.id_use_persistence = wx.NewId()
         self.id_peak_hold = wx.NewId()
         
         self.plot.Bind(wx.EVT_MENU, self.on_average, id=self.id_average)
+        self.plot.Bind(wx.EVT_MENU, self.on_use_persistence, id=self.id_use_persistence)
         self.plot.Bind(wx.EVT_MENU, self.on_peak_hold, id=self.id_peak_hold)
         self.plot.Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level)
         self.plot.Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level)
@@ -511,6 +542,7 @@ class fft_window (wx.Panel):
         menu = wx.Menu()
         self.popup_menu = menu
         menu.AppendCheckItem(self.id_average, "Average")
+        menu.AppendCheckItem(self.id_use_persistence, "Persistence")
         menu.AppendCheckItem(self.id_peak_hold, "Peak Hold")
         menu.Append(self.id_incr_ref_level, "Incr Ref Level")
         menu.Append(self.id_decr_ref_level, "Decr Ref Level")
@@ -526,6 +558,7 @@ class fft_window (wx.Panel):
 
         self.checkmarks = {
             self.id_average : lambda : self.fftsink.average,
+            self.id_use_persistence : lambda : self.fftsink.use_persistence,
             self.id_peak_hold : lambda : self.fftsink.peak_hold,
             self.id_y_per_div_1 : lambda : self.fftsink.y_per_div == 1,
             self.id_y_per_div_2 : lambda : self.fftsink.y_per_div == 2,
@@ -568,11 +601,11 @@ class test_app_block (stdgui2.std_top_block):
         fft_size = 256
 
         # build our flow graph
-        input_rate = 20.48e3
+        input_rate = 100*20.48e3
 
         # Generate a complex sinusoid
-        #src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 2e3, 1)
-        src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1)
+        #src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 100*2e3, 1)
+        src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 100*5.75e3, 1)
 
         # We add these throttle blocks so that this demo doesn't
         # suck down all the CPU available.  Normally you wouldn't use these.
@@ -585,8 +618,8 @@ class test_app_block (stdgui2.std_top_block):
 
         self.connect(src1, thr1, sink1)
 
-        #src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 2e3, 1)
-        src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1)
+        #src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 100*2e3, 1)
+        src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 100*5.75e3, 1)
         thr2 = gr.throttle(gr.sizeof_float, input_rate)
         sink2 = fft_sink_f (panel, title="Real Data", fft_size=fft_size*2,
                             sample_rate=input_rate, baseband_freq=100e3,