commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r9287 - gnuradio/branches/developers/jblum/glwxgui/gr-


From: jcorgan
Subject: [Commit-gnuradio] r9287 - gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python
Date: Thu, 14 Aug 2008 10:25:51 -0600 (MDT)

Author: jcorgan
Date: 2008-08-14 10:25:51 -0600 (Thu, 14 Aug 2008)
New Revision: 9287

Added:
   
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/fftsink_nongl.py
   
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/scopesink_nongl.py
   
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/waterfallsink_nongl.py
Removed:
   
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/fftsink2_old.py
   
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/scopesink2_old.py
   
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/waterfallsink2_old.py
Modified:
   gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/Makefile.am
   gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/fftsink2.py
   gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/form.py
   gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/powermate.py
   gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/scopesink2.py
   gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/slider.py
   
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/waterfallsink2.py
Log:
Rename nongl files and clean up properties.

Modified: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/Makefile.am
===================================================================
--- gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/Makefile.am  
2008-08-14 16:19:53 UTC (rev 9286)
+++ gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/Makefile.am  
2008-08-14 16:25:51 UTC (rev 9287)
@@ -38,7 +38,7 @@
        const_window.py                 \
        form.py                         \
        fftsink2.py                     \
-       fftsink2_old.py                 \
+       fftsink_nongl.py                \
        fftsink_gl.py                   \
        fft_window.py                   \
        numbersink2.py                  \
@@ -47,11 +47,11 @@
        powermate.py                    \
        pubsub.py                       \
        scopesink2.py                   \
-       scopesink2_old.py               \
+       scopesink_nongl.py              \
        scopesink_gl.py                 \
        scope_window.py                 \
        waterfallsink2.py               \
-       waterfallsink2_old.py           \
+       waterfallsink_nongl.py          \
        waterfallsink_gl.py             \
        waterfall_window.py             \
        slider.py                       \

Modified: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/fftsink2.py
===================================================================
--- gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/fftsink2.py  
2008-08-14 16:19:53 UTC (rev 9286)
+++ gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/fftsink2.py  
2008-08-14 16:25:51 UTC (rev 9287)
@@ -24,12 +24,12 @@
 p = gr.prefs()
 style = p.get_string('wxgui', 'style', 'auto')
 
-# In 3.2 we'll change 'auto' to mean 'gl'
+# In 3.2 we'll change 'auto' to mean 'gl' if possible, then fallback
 if style == 'auto':
     style = 'nongl'
 
 if style == 'nongl':
-    from fftsink2_old import fft_sink_f, fft_sink_c
+    from fftsink_nongl import fft_sink_f, fft_sink_c
 elif style == 'gl':
     try:
         import wx

Deleted: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/fftsink2_old.py

Copied: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/fftsink_nongl.py 
(from rev 9284, 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/fftsink2_old.py)
===================================================================
--- 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/fftsink_nongl.py 
                            (rev 0)
+++ 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/fftsink_nongl.py 
    2008-08-14 16:25:51 UTC (rev 9287)
@@ -0,0 +1,603 @@
+#!/usr/bin/env python
+#
+# Copyright 2003,2004,2005,2006,2007 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, gru, window
+from gnuradio.wxgui import stdgui2
+import wx
+import plot
+import numpy
+import threading
+import math    
+
+DIV_LEVELS = (1, 2, 5, 10, 20)
+
+default_fftsink_size = (640,240)
+default_fft_rate = gr.prefs().get_long('wxgui', 'fft_rate', 15)
+
+class fft_sink_base(object):
+    def __init__(self, input_is_real=False, baseband_freq=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='', peak_hold=False):
+
+        # initialize common attributes
+        self.baseband_freq = baseband_freq
+        self.y_per_div=y_per_div
+        self.y_divs = y_divs
+        self.ref_level = ref_level
+        self.sample_rate = sample_rate
+        self.fft_size = fft_size
+        self.fft_rate = fft_rate
+        self.average = average
+        if avg_alpha is None:
+            self.avg_alpha = 2.0 / fft_rate
+        else:
+            self.avg_alpha = avg_alpha
+        self.title = title
+        self.peak_hold = peak_hold
+        self.input_is_real = input_is_real
+        self.msgq = gr.msg_queue(2)         # queue that holds a maximum of 2 
messages
+
+    def set_y_per_div(self, y_per_div):
+        self.y_per_div = y_per_div
+
+    def set_ref_level(self, ref_level):
+        self.ref_level = ref_level
+
+    def set_average(self, average):
+        self.average = average
+        if average:
+            self.avg.set_taps(self.avg_alpha)
+        else:
+            self.avg.set_taps(1.0)
+        self.win.peak_vals = None
+        
+    def set_peak_hold(self, enable):
+        self.peak_hold = enable
+        self.win.set_peak_hold(enable)
+
+    def set_avg_alpha(self, avg_alpha):
+        self.avg_alpha = avg_alpha
+
+    def set_baseband_freq(self, baseband_freq):
+        self.baseband_freq = baseband_freq
+
+    def set_sample_rate(self, sample_rate):
+        self.sample_rate = sample_rate
+        self._set_n()
+
+    def _set_n(self):
+        self.one_in_n.set_n(max(1, 
int(self.sample_rate/self.fft_size/self.fft_rate)))
+        
+
+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):
+
+        gr.hier_block2.__init__(self, "fft_sink_f",
+                                gr.io_signature(1, 1, gr.sizeof_float),
+                                gr.io_signature(0,0,0))
+
+        fft_sink_base.__init__(self, input_is_real=True, 
baseband_freq=baseband_freq,
+                               y_per_div=y_per_div, y_divs=y_divs, 
ref_level=ref_level,
+                               sample_rate=sample_rate, fft_size=fft_size,
+                               fft_rate=fft_rate,
+                               average=average, avg_alpha=avg_alpha, 
title=title,
+                               peak_hold=peak_hold)
+                               
+        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,
+                                         max(1, 
int(self.sample_rate/self.fft_size/self.fft_rate)))
+        
+        mywindow = window.blackmanharris(self.fft_size)
+        self.fft = gr.fft_vfc(self.fft_size, True, mywindow)
+        power = 0
+        for tap in mywindow:
+            power += tap*tap
+            
+        self.c2mag = gr.complex_to_mag(self.fft_size)
+        self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size)
+
+        # FIXME  We need to add 3dB to all bins but the DC bin
+        self.log = gr.nlog10_ff(20, self.fft_size,
+                               -10*math.log10(self.fft_size)                # 
Adjust for number of bins
+                               -10*math.log10(power/self.fft_size)        # 
Adjust for windowing loss
+                               -20*math.log10(ref_scale/2))                # 
Adjust for reference scale
+                               
+        self.sink = gr.message_sink(gr.sizeof_float * self.fft_size, 
self.msgq, True)
+        self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, 
self.avg, self.log, self.sink)
+
+        self.win = fft_window(self, parent, size=size)
+        self.set_average(self.average)
+        self.set_peak_hold(self.peak_hold)
+
+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):
+
+        gr.hier_block2.__init__(self, "fft_sink_c",
+                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
+                                gr.io_signature(0,0,0))
+
+        fft_sink_base.__init__(self, input_is_real=False, 
baseband_freq=baseband_freq,
+                               y_per_div=y_per_div, y_divs=y_divs, 
ref_level=ref_level,
+                               sample_rate=sample_rate, fft_size=fft_size,
+                               fft_rate=fft_rate,
+                               average=average, avg_alpha=avg_alpha, 
title=title,
+                               peak_hold=peak_hold)
+
+        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,
+                                         max(1, 
int(self.sample_rate/self.fft_size/self.fft_rate)))
+        
+        mywindow = window.blackmanharris(self.fft_size)
+        self.fft = gr.fft_vcc(self.fft_size, True, mywindow)
+        power = 0
+        for tap in mywindow:
+            power += tap*tap
+            
+        self.c2mag = gr.complex_to_mag(self.fft_size)
+        self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size)
+
+        # FIXME  We need to add 3dB to all bins but the DC bin
+        self.log = gr.nlog10_ff(20, self.fft_size,
+                                -10*math.log10(self.fft_size)                # 
Adjust for number of bins
+                                -10*math.log10(power/self.fft_size)        # 
Adjust for windowing loss
+                                -20*math.log10(ref_scale/2))                # 
Adjust for reference scale
+                                
+        self.sink = gr.message_sink(gr.sizeof_float * self.fft_size, 
self.msgq, True)
+        self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, 
self.avg, self.log, self.sink)
+
+        self.win = fft_window(self, parent, size=size)
+        self.set_average(self.average)
+        self.set_peak_hold(self.peak_hold)
+
+
+# ------------------------------------------------------------------------
+
+myDATA_EVENT = wx.NewEventType()
+EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0)
+
+
+class DataEvent(wx.PyEvent):
+    def __init__(self, data):
+        wx.PyEvent.__init__(self)
+        self.SetEventType (myDATA_EVENT)
+        self.data = data
+
+    def Clone (self): 
+        self.__class__ (self.GetId())
+
+
+class input_watcher (threading.Thread):
+    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 ()
+
+    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())
+
+            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]
+
+            complex_data = numpy.fromstring (s, numpy.float32)
+            de = DataEvent (complex_data)
+            wx.PostEvent (self.event_receiver, de)
+            del de
+
+class control_panel(wx.Panel):
+    
+    class LabelText(wx.StaticText):    
+        def __init__(self, window, label):
+            wx.StaticText.__init__(self, window, -1, label)
+            font = self.GetFont()
+            font.SetWeight(wx.FONTWEIGHT_BOLD)
+            font.SetUnderlined(True)
+            self.SetFont(font)
+    
+    def __init__(self, parent):
+        self.parent = parent
+        wx.Panel.__init__(self, parent, -1, style=wx.SIMPLE_BORDER)    
+        control_box = wx.BoxSizer(wx.VERTICAL)
+        
+        #checkboxes for average and peak hold
+        control_box.AddStretchSpacer()
+        control_box.Add(self.LabelText(self, 'Options'), 0, wx.ALIGN_CENTER)
+        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.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)
+       
+        #radio buttons for div size
+        control_box.AddStretchSpacer()
+        control_box.Add(self.LabelText(self, 'Set dB/div'), 0, wx.ALIGN_CENTER)
+        radio_box = wx.BoxSizer(wx.VERTICAL)
+        self.radio_buttons = list()
+        for y_per_div in DIV_LEVELS:
+            radio_button = wx.RadioButton(self, -1, "%d dB/div"%y_per_div)
+            radio_button.Bind(wx.EVT_RADIOBUTTON, self.on_radio_button_change)
+            self.radio_buttons.append(radio_button)
+            radio_box.Add(radio_button, 0, wx.ALIGN_LEFT)
+        control_box.Add(radio_box, 0, wx.EXPAND)
+        
+        #ref lvl buttons
+        control_box.AddStretchSpacer()
+        control_box.Add(self.LabelText(self, 'Adj Ref Lvl'), 0, 
wx.ALIGN_CENTER)
+        control_box.AddSpacer(2)
+        button_box = wx.BoxSizer(wx.HORIZONTAL)        
+        self.ref_plus_button = wx.Button(self, -1, '+', style=wx.BU_EXACTFIT)
+        self.ref_plus_button.Bind(wx.EVT_BUTTON, parent.on_incr_ref_level)
+        button_box.Add(self.ref_plus_button, 0, wx.ALIGN_CENTER)
+        self.ref_minus_button = wx.Button(self, -1, ' - ', 
style=wx.BU_EXACTFIT)
+        self.ref_minus_button.Bind(wx.EVT_BUTTON, parent.on_decr_ref_level)
+        button_box.Add(self.ref_minus_button, 0, wx.ALIGN_CENTER)
+        control_box.Add(button_box, 0, wx.ALIGN_CENTER)
+        control_box.AddStretchSpacer()
+        #set sizer
+        self.SetSizerAndFit(control_box)
+        #update
+        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.peak_hold_check_box.SetValue(self.parent.fftsink.peak_hold)
+        #update radio buttons    
+        try:
+            index = list(DIV_LEVELS).index(self.parent.fftsink.y_per_div)
+            self.radio_buttons[index].SetValue(True)
+        except: pass
+        
+    def on_radio_button_change(self, evt):
+        selected_radio_button = filter(lambda rb: rb.GetValue(), 
self.radio_buttons)[0] 
+        index = self.radio_buttons.index(selected_radio_button)
+        self.parent.fftsink.set_y_per_div(DIV_LEVELS[index])
+
+class fft_window (wx.Panel):
+    def __init__ (self, fftsink, parent, id = -1,
+                  pos = wx.DefaultPosition, size = wx.DefaultSize,
+                  style = wx.DEFAULT_FRAME_STYLE, name = ""):
+        
+        self.fftsink = fftsink
+        #init panel and plot 
+        wx.Panel.__init__(self, parent, -1)                  
+        self.plot = plot.PlotCanvas(self, id, pos, size, style, name)       
+        #setup the box with plot and controls
+        self.control_panel = control_panel(self)
+        main_box = wx.BoxSizer (wx.HORIZONTAL)
+        main_box.Add (self.plot, 1, wx.EXPAND)
+        main_box.Add (self.control_panel, 0, wx.EXPAND)
+        self.SetSizerAndFit(main_box)
+        
+        self.peak_hold = False
+        self.peak_vals = None
+        
+        self.plot.SetEnableGrid (True)
+        # self.SetEnableZoom (True)
+        # self.SetBackgroundColour ('black')
+        
+        self.build_popup_menu()
+        self.set_baseband_freq(0.0)
+                
+        EVT_DATA_EVENT (self, self.set_data)
+        wx.EVT_CLOSE (self, self.on_close_window)
+        self.plot.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
+        self.plot.Bind(wx.EVT_MOTION, self.evt_motion)
+        
+        self.input_watcher = input_watcher(fftsink.msgq, fftsink.fft_size, 
self)
+
+    def set_scale(self, freq):
+        x = max(abs(self.fftsink.sample_rate), 
abs(self.fftsink.baseband_freq))        
+        if x >= 1e9:
+            self._scale_factor = 1e-9
+            self._units = "GHz"
+            self._format = "%3.6f"
+        elif x >= 1e6:
+            self._scale_factor = 1e-6
+            self._units = "MHz"
+            self._format = "%3.3f"
+        else:
+            self._scale_factor = 1e-3
+            self._units = "kHz"
+            self._format = "%3.3f"
+
+    def set_baseband_freq(self, baseband_freq):
+        if self.peak_hold:
+            self.peak_vals = None
+        self.set_scale(baseband_freq)
+        self.fftsink.set_baseband_freq(baseband_freq)
+        
+    def on_close_window (self, event):
+        print "fft_window:on_close_window"
+        self.keep_running = False
+
+
+    def set_data (self, evt):
+        dB = evt.data
+        L = len (dB)
+
+        if self.peak_hold:
+            if self.peak_vals is None:
+                self.peak_vals = dB
+            else:
+                self.peak_vals = numpy.maximum(dB, self.peak_vals)
+
+        if self.fftsink.input_is_real:     # only plot 1/2 the points
+            x_vals = ((numpy.arange (L/2) * (self.fftsink.sample_rate 
+                       * self._scale_factor / L))
+                      + self.fftsink.baseband_freq * self._scale_factor)
+            self._points = numpy.zeros((len(x_vals), 2), numpy.float64)
+            self._points[:,0] = x_vals
+            self._points[:,1] = dB[0:L/2]
+            if self.peak_hold:
+                self._peak_points = numpy.zeros((len(x_vals), 2), 
numpy.float64)
+                self._peak_points[:,0] = x_vals
+                self._peak_points[:,1] = self.peak_vals[0:L/2]
+        else:
+            # the "negative freqs" are in the second half of the array
+            x_vals = ((numpy.arange (-L/2, L/2)
+                       * (self.fftsink.sample_rate * self._scale_factor / L))
+                      + self.fftsink.baseband_freq * self._scale_factor)
+            self._points = numpy.zeros((len(x_vals), 2), numpy.float64)
+            self._points[:,0] = x_vals
+            self._points[:,1] = numpy.concatenate ((dB[L/2:], dB[0:L/2]))
+            if self.peak_hold:
+                self._peak_points = numpy.zeros((len(x_vals), 2), 
numpy.float64)
+                self._peak_points[:,0] = x_vals
+                self._peak_points[:,1] = numpy.concatenate 
((self.peak_vals[L/2:], self.peak_vals[0:L/2]))
+
+        lines = [plot.PolyLine (self._points, colour='BLUE'),]
+        if self.peak_hold:
+            lines.append(plot.PolyLine (self._peak_points, colour='GREEN'))
+
+        graphics = plot.PlotGraphics (lines,
+                                      title=self.fftsink.title,
+                                      xLabel = self._units, yLabel = "dB")
+        x_range = x_vals[0], x_vals[-1]
+        ymax = self.fftsink.ref_level
+        ymin = self.fftsink.ref_level - self.fftsink.y_per_div * 
self.fftsink.y_divs
+        y_range = ymin, ymax
+        self.plot.Draw (graphics, xAxis=x_range, yAxis=y_range, 
step=self.fftsink.y_per_div)        
+
+    def set_peak_hold(self, enable):
+        self.peak_hold = enable
+        self.peak_vals = None
+
+    def on_average(self, evt):
+        # print "on_average"
+        self.fftsink.set_average(evt.IsChecked())
+        self.control_panel.update()
+
+    def on_peak_hold(self, evt):
+        # print "on_peak_hold"
+        self.fftsink.set_peak_hold(evt.IsChecked())
+        self.control_panel.update()
+
+    def on_incr_ref_level(self, evt):
+        # print "on_incr_ref_level"
+        self.fftsink.set_ref_level(self.fftsink.ref_level
+                                   + self.fftsink.y_per_div)
+
+    def on_decr_ref_level(self, evt):
+        # print "on_decr_ref_level"
+        self.fftsink.set_ref_level(self.fftsink.ref_level
+                                   - self.fftsink.y_per_div)
+
+    def on_incr_y_per_div(self, evt):
+        # print "on_incr_y_per_div"
+        self.fftsink.set_y_per_div(next_up(self.fftsink.y_per_div, DIV_LEVELS))
+        self.control_panel.update()
+
+    def on_decr_y_per_div(self, evt):
+        # print "on_decr_y_per_div"
+        self.fftsink.set_y_per_div(next_down(self.fftsink.y_per_div, 
DIV_LEVELS))
+        self.control_panel.update()
+
+    def on_y_per_div(self, evt):
+        # print "on_y_per_div"
+        Id = evt.GetId()
+        if Id == self.id_y_per_div_1:
+            self.fftsink.set_y_per_div(1)
+        elif Id == self.id_y_per_div_2:
+            self.fftsink.set_y_per_div(2)
+        elif Id == self.id_y_per_div_5:
+            self.fftsink.set_y_per_div(5)
+        elif Id == self.id_y_per_div_10:
+            self.fftsink.set_y_per_div(10)
+        elif Id == self.id_y_per_div_20:
+            self.fftsink.set_y_per_div(20)
+        self.control_panel.update()
+
+    def on_right_click(self, event):
+        menu = self.popup_menu
+        for id, pred in self.checkmarks.items():
+            item = menu.FindItemById(id)
+            item.Check(pred())
+        self.plot.PopupMenu(menu, event.GetPosition())
+
+    def evt_motion(self, event):
+        if not hasattr(self, "_points"):
+            return # Got here before first window data update
+            
+        # Clip to plotted values
+        (ux, uy) = self.plot.GetXY(event)      # Scaled position
+        x_vals = numpy.array(self._points[:,0])
+        if ux < x_vals[0] or ux > x_vals[-1]:
+            tip = self.GetToolTip()
+            if tip:
+                tip.Enable(False)
+            return
+
+        # Get nearest X value (is there a better way)?
+        ind = numpy.argmin(numpy.abs(x_vals-ux))
+        x_val = x_vals[ind]
+        db_val = self._points[ind, 1]
+        text = (self._format+" %s dB=%3.3f") % (x_val, self._units, db_val)
+
+        # Display the tooltip
+        tip = wx.ToolTip(text)
+        tip.Enable(True)
+        tip.SetDelay(0)
+        self.SetToolTip(tip)
+        
+    def build_popup_menu(self):
+        self.id_incr_ref_level = wx.NewId()
+        self.id_decr_ref_level = wx.NewId()
+        self.id_incr_y_per_div = wx.NewId()
+        self.id_decr_y_per_div = wx.NewId()
+        self.id_y_per_div_1 = wx.NewId()
+        self.id_y_per_div_2 = wx.NewId()
+        self.id_y_per_div_5 = wx.NewId()
+        self.id_y_per_div_10 = wx.NewId()
+        self.id_y_per_div_20 = wx.NewId()
+        self.id_average = 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_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)
+        self.plot.Bind(wx.EVT_MENU, self.on_incr_y_per_div, 
id=self.id_incr_y_per_div)
+        self.plot.Bind(wx.EVT_MENU, self.on_decr_y_per_div, 
id=self.id_decr_y_per_div)
+        self.plot.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_1)
+        self.plot.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_2)
+        self.plot.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_5)
+        self.plot.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_10)
+        self.plot.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_20)
+        
+        # make a menu
+        menu = wx.Menu()
+        self.popup_menu = menu
+        menu.AppendCheckItem(self.id_average, "Average")
+        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")
+        # menu.Append(self.id_incr_y_per_div, "Incr dB/div")
+        # menu.Append(self.id_decr_y_per_div, "Decr dB/div")
+        menu.AppendSeparator()
+        # we'd use RadioItems for these, but they're not supported on Mac
+        menu.AppendCheckItem(self.id_y_per_div_1, "1 dB/div")
+        menu.AppendCheckItem(self.id_y_per_div_2, "2 dB/div")
+        menu.AppendCheckItem(self.id_y_per_div_5, "5 dB/div")
+        menu.AppendCheckItem(self.id_y_per_div_10, "10 dB/div")
+        menu.AppendCheckItem(self.id_y_per_div_20, "20 dB/div")
+
+        self.checkmarks = {
+            self.id_average : lambda : self.fftsink.average,
+            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,
+            self.id_y_per_div_5 : lambda : self.fftsink.y_per_div == 5,
+            self.id_y_per_div_10 : lambda : self.fftsink.y_per_div == 10,
+            self.id_y_per_div_20 : lambda : self.fftsink.y_per_div == 20,
+            }
+
+
+def next_up(v, seq):
+    """
+    Return the first item in seq that is > v.
+    """
+    for s in seq:
+        if s > v:
+            return s
+    return v
+
+def next_down(v, seq):
+    """
+    Return the last item in seq that is < v.
+    """
+    rseq = list(seq[:])
+    rseq.reverse()
+
+    for s in rseq:
+        if s < v:
+            return s
+    return v
+
+
+# ----------------------------------------------------------------
+# Standalone test app
+# ----------------------------------------------------------------
+
+class test_app_block (stdgui2.std_top_block):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv)
+
+        fft_size = 256
+
+        # build our flow graph
+        input_rate = 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)
+
+        # We add these throttle blocks so that this demo doesn't
+        # suck down all the CPU available.  Normally you wouldn't use these.
+        thr1 = gr.throttle(gr.sizeof_gr_complex, input_rate)
+
+        sink1 = fft_sink_c (panel, title="Complex Data", fft_size=fft_size,
+                            sample_rate=input_rate, baseband_freq=100e3,
+                            ref_level=0, y_per_div=20, y_divs=10)
+        vbox.Add (sink1.win, 1, wx.EXPAND)
+
+        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)
+        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,
+                            ref_level=0, y_per_div=20, y_divs=10)
+        vbox.Add (sink2.win, 1, wx.EXPAND)
+
+        self.connect(src2, thr2, sink2)
+
+def main ():
+    app = stdgui2.stdapp (test_app_block, "FFT Sink Test App")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()


Property changes on: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/fftsink_nongl.py
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native


Property changes on: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/form.py
___________________________________________________________________
Name: svn:executable
   - *


Property changes on: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/powermate.py
___________________________________________________________________
Name: svn:executable
   - *

Modified: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/scopesink2.py
===================================================================
--- 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/scopesink2.py    
    2008-08-14 16:19:53 UTC (rev 9286)
+++ 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/scopesink2.py    
    2008-08-14 16:25:51 UTC (rev 9287)
@@ -24,12 +24,12 @@
 p = gr.prefs()
 style = p.get_string('wxgui', 'style', 'auto')
 
-# In 3.2 we'll change 'auto' to mean 'gl'
+# In 3.2 we'll change 'auto' to mean 'gl' if possible, then fallback
 if style == 'auto':
     style = 'nongl'
 
 if style == 'nongl':
-    from scopesink2_old import scope_sink_f, scope_sink_c
+    from scopesink_nongl import scope_sink_f, scope_sink_c
 elif style == 'gl':
     try:
         import wx

Deleted: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/scopesink2_old.py

Copied: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/scopesink_nongl.py
 (from rev 9284, 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/scopesink2_old.py)
===================================================================
--- 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/scopesink_nongl.py
                           (rev 0)
+++ 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/scopesink_nongl.py
   2008-08-14 16:25:51 UTC (rev 9287)
@@ -0,0 +1,661 @@
+#!/usr/bin/env python
+#
+# Copyright 2003,2004,2006,2007 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, gru, eng_notation
+from gnuradio.wxgui import stdgui2
+import wx
+import gnuradio.wxgui.plot as plot
+import numpy
+import threading
+import struct
+
+default_scopesink_size = (640, 240)
+default_v_scale = 1000
+default_frame_decim = gr.prefs().get_long('wxgui', 'frame_decim', 1)
+
+class scope_sink_f(gr.hier_block2):
+    def __init__(self, parent, title='', sample_rate=1,
+                 size=default_scopesink_size, frame_decim=default_frame_decim,
+                 v_scale=default_v_scale, t_scale=None, num_inputs=1):
+
+        gr.hier_block2.__init__(self, "scope_sink_f",
+                                gr.io_signature(num_inputs, num_inputs, 
gr.sizeof_float),
+                                gr.io_signature(0,0,0))
+
+        msgq = gr.msg_queue(2)         # message queue that holds at most 2 
messages
+        self.guts = gr.oscope_sink_f(sample_rate, msgq)
+        for i in range(num_inputs):        
+          self.connect((self, i), (self.guts, i))
+
+        self.win = scope_window(win_info (msgq, sample_rate, frame_decim,
+                                          v_scale, t_scale, self.guts, title), 
parent)
+
+    def set_sample_rate(self, sample_rate):
+        self.guts.set_sample_rate(sample_rate)
+        self.win.info.set_sample_rate(sample_rate)
+
+class scope_sink_c(gr.hier_block2):
+    def __init__(self, parent, title='', sample_rate=1,
+                 size=default_scopesink_size, frame_decim=default_frame_decim,
+                 v_scale=default_v_scale, t_scale=None, num_inputs=1):
+
+        gr.hier_block2.__init__(self, "scope_sink_c",
+                                gr.io_signature(num_inputs, num_inputs, 
gr.sizeof_gr_complex),
+                                gr.io_signature(0,0,0))
+
+        msgq = gr.msg_queue(2)         # message queue that holds at most 2 
messages
+        self.guts = gr.oscope_sink_f(sample_rate, msgq)
+        for i in range(num_inputs):      
+               c2f = gr.complex_to_float()  
+               self.connect((self, i), c2f)
+               self.connect((c2f, 0), (self.guts, 2*i+0))
+               self.connect((c2f, 1), (self.guts, 2*i+1))
+        
+        self.win = scope_window(win_info(msgq, sample_rate, frame_decim,
+                                         v_scale, t_scale, self.guts, title), 
parent)
+        
+    def set_sample_rate(self, sample_rate):
+        self.guts.set_sample_rate(sample_rate)
+        self.win.info.set_sample_rate(sample_rate)
+
+class constellation_sink(scope_sink_c):
+    def __init__(self, parent, title='Constellation', sample_rate=1,
+                 size=default_scopesink_size, frame_decim=default_frame_decim):
+        scope_sink_c.__init__(self, parent=parent, title=title, 
sample_rate=sample_rate,
+                 size=size, frame_decim=frame_decim)
+        self.win.info.xy = True        #constellation mode
+
+# ========================================================================
+
+
+time_base_list = [                      # time / division
+    1.0e-7,   # 100ns / div
+    2.5e-7,
+    5.0e-7,
+    1.0e-6,   #   1us / div
+    2.5e-6,
+    5.0e-6,
+    1.0e-5,   #  10us / div
+    2.5e-5,
+    5.0e-5,
+    1.0e-4,   # 100us / div
+    2.5e-4,
+    5.0e-4,
+    1.0e-3,   #   1ms / div
+    2.5e-3,
+    5.0e-3,
+    1.0e-2,   #  10ms / div
+    2.5e-2,
+    5.0e-2
+    ]
+
+v_scale_list = [ # counts / div, LARGER gains are SMALLER /div, appear EARLIER
+    2.0e-3,   # 2m / div, don't call it V/div it's actually counts/div
+    5.0e-3,
+    1.0e-2,
+    2.0e-2,
+    5.0e-2,
+    1.0e-1,
+    2.0e-1,
+    5.0e-1,
+    1.0e+0,
+    2.0e+0,
+    5.0e+0,
+    1.0e+1,
+    2.0e+1,
+    5.0e+1,
+    1.0e+2,
+    2.0e+2,
+    5.0e+2,
+    1.0e+3,
+    2.0e+3,
+    5.0e+3,
+    1.0e+4 # 10000 /div, USRP full scale is -/+ 32767
+    ]
+
+    
+wxDATA_EVENT = wx.NewEventType()
+
+def EVT_DATA_EVENT(win, func):
+    win.Connect(-1, -1, wxDATA_EVENT, func)
+
+class DataEvent(wx.PyEvent):
+    def __init__(self, data):
+        wx.PyEvent.__init__(self)
+        self.SetEventType (wxDATA_EVENT)
+        self.data = data
+
+    def Clone (self): 
+        self.__class__ (self.GetId())
+
+
+class win_info (object):
+    __slots__ = ['msgq', 'sample_rate', 'frame_decim', 'v_scale', 
+                 'scopesink', 'title',
+                 'time_scale_cursor', 'v_scale_cursor', 'marker', 'xy',
+                 'autorange', 'running']
+
+    def __init__ (self, msgq, sample_rate, frame_decim, v_scale, t_scale,
+                  scopesink, title = "Oscilloscope", xy=False):
+        self.msgq = msgq
+        self.sample_rate = sample_rate
+        self.frame_decim = frame_decim
+        self.scopesink = scopesink
+        self.title = title;
+
+        self.time_scale_cursor = gru.seq_with_cursor(time_base_list, 
initial_value = t_scale)
+        self.v_scale_cursor = gru.seq_with_cursor(v_scale_list, initial_value 
= v_scale)
+
+        self.marker = 'line'
+        self.xy = xy
+        if v_scale == None:        # 0 and None are both False, but 0 != None
+            self.autorange = True
+        else:
+            self.autorange = False # 0 is a valid v_scale            
+        self.running = True
+
+    def get_time_per_div (self):
+        return self.time_scale_cursor.current ()
+
+    def get_volts_per_div (self):
+        return self.v_scale_cursor.current ()
+
+    def set_sample_rate(self, sample_rate):
+        self.sample_rate = sample_rate
+        
+    def get_sample_rate (self):
+        return self.sample_rate
+
+    def get_decimation_rate (self):
+        return 1.0
+
+    def set_marker (self, s):
+        self.marker = s
+
+    def get_marker (self):
+        return self.marker
+
+
+class input_watcher (threading.Thread):
+    def __init__ (self, msgq, event_receiver, frame_decim, **kwds):
+        threading.Thread.__init__ (self, **kwds)
+        self.setDaemon (1)
+        self.msgq = msgq
+        self.event_receiver = event_receiver
+        self.frame_decim = frame_decim
+        self.iscan = 0
+        self.keep_running = True
+        self.start ()
+
+    def run (self):
+        # print "input_watcher: pid = ", os.getpid ()
+        while (self.keep_running):
+            msg = self.msgq.delete_head()   # blocking read of message queue
+            if self.iscan == 0:            # only display at frame_decim
+                self.iscan = self.frame_decim
+                                
+                nchan = int(msg.arg1())    # number of channels of data in msg
+                nsamples = int(msg.arg2()) # number of samples in each channel
+
+                s = msg.to_string()      # get the body of the msg as a string
+
+                bytes_per_chan = nsamples * gr.sizeof_float
+
+                records = []
+                for ch in range (nchan):
+
+                    start = ch * bytes_per_chan
+                    chan_data = s[start:start+bytes_per_chan]
+                    rec = numpy.fromstring (chan_data, numpy.float32)
+                    records.append (rec)
+
+                # print "nrecords = %d, reclen = %d" % (len (records),nsamples)
+
+                de = DataEvent (records)
+                wx.PostEvent (self.event_receiver, de)
+                records = []
+                del de
+
+            # end if iscan == 0
+            self.iscan -= 1
+    
+
+class scope_window (wx.Panel):
+
+    def __init__ (self, info, parent, id = -1,
+                  pos = wx.DefaultPosition, size = wx.DefaultSize, name = ""):
+        wx.Panel.__init__ (self, parent, -1)
+        self.info = info
+
+        vbox = wx.BoxSizer (wx.VERTICAL)
+
+        self.graph = graph_window (info, self, -1)
+
+        vbox.Add (self.graph, 1, wx.EXPAND)
+        vbox.Add (self.make_control_box(), 0, wx.EXPAND)
+        vbox.Add (self.make_control2_box(), 0, wx.EXPAND)
+
+        self.sizer = vbox
+        self.SetSizer (self.sizer)
+        self.SetAutoLayout (True)
+        self.sizer.Fit (self)
+        self.set_autorange(self.info.autorange)
+        
+
+    # second row of control buttons etc. appears BELOW control_box
+    def make_control2_box (self):
+        ctrlbox = wx.BoxSizer (wx.HORIZONTAL)
+
+        self.inc_v_button = wx.Button (self, 1101, " < ", style=wx.BU_EXACTFIT)
+        self.inc_v_button.SetToolTipString ("Increase vertical range")
+        wx.EVT_BUTTON (self, 1101, self.incr_v_scale) # ID matches button ID 
above
+
+        self.dec_v_button  = wx.Button (self, 1100, " > ", 
style=wx.BU_EXACTFIT)
+        self.dec_v_button.SetToolTipString ("Decrease vertical range")
+        wx.EVT_BUTTON (self, 1100, self.decr_v_scale)
+
+        self.v_scale_label = wx.StaticText (self, 1002, "None") # vertical /div
+        self.update_v_scale_label ()
+
+        self.autorange_checkbox = wx.CheckBox (self, 1102, "Autorange")
+        self.autorange_checkbox.SetToolTipString ("Select autorange on/off")
+        wx.EVT_CHECKBOX(self, 1102, self.autorange_checkbox_event)
+
+        ctrlbox.Add ((5,0) ,0) # left margin space
+        ctrlbox.Add (self.inc_v_button, 0, wx.EXPAND)
+        ctrlbox.Add (self.dec_v_button, 0, wx.EXPAND)
+        ctrlbox.Add (self.v_scale_label, 0, wx.ALIGN_CENTER)
+        ctrlbox.Add ((20,0) ,0) # spacer
+        ctrlbox.Add (self.autorange_checkbox, 0, wx.ALIGN_CENTER)
+
+        return ctrlbox
+
+    def make_control_box (self):
+        ctrlbox = wx.BoxSizer (wx.HORIZONTAL)
+
+        tb_left = wx.Button (self, 1001, " < ", style=wx.BU_EXACTFIT)
+        tb_left.SetToolTipString ("Increase time base")
+        wx.EVT_BUTTON (self, 1001, self.incr_timebase)
+
+
+        tb_right  = wx.Button (self, 1000, " > ", style=wx.BU_EXACTFIT)
+        tb_right.SetToolTipString ("Decrease time base")
+        wx.EVT_BUTTON (self, 1000, self.decr_timebase)
+
+        self.time_base_label = wx.StaticText (self, 1002, "")
+        self.update_timebase_label ()
+
+        ctrlbox.Add ((5,0) ,0)
+        # ctrlbox.Add (wx.StaticText (self, -1, "Horiz Scale: "), 0, 
wx.ALIGN_CENTER)
+        ctrlbox.Add (tb_left, 0, wx.EXPAND)
+        ctrlbox.Add (tb_right, 0, wx.EXPAND)
+        ctrlbox.Add (self.time_base_label, 0, wx.ALIGN_CENTER)
+
+        ctrlbox.Add ((10,0) ,1)            # stretchy space
+
+        ctrlbox.Add (wx.StaticText (self, -1, "Trig: "), 0, wx.ALIGN_CENTER)
+        self.trig_chan_choice = wx.Choice (self, 1004,
+                                           choices = ['Ch1', 'Ch2', 'Ch3', 
'Ch4'])
+        self.trig_chan_choice.SetToolTipString ("Select channel for trigger")
+        wx.EVT_CHOICE (self, 1004, self.trig_chan_choice_event)
+        ctrlbox.Add (self.trig_chan_choice, 0, wx.ALIGN_CENTER)
+
+        self.trig_mode_choice = wx.Choice (self, 1005,
+                                           choices = ['Auto', 'Pos', 'Neg'])
+        self.trig_mode_choice.SetToolTipString ("Select trigger slope or Auto 
(untriggered roll)")
+        wx.EVT_CHOICE (self, 1005, self.trig_mode_choice_event)
+        ctrlbox.Add (self.trig_mode_choice, 0, wx.ALIGN_CENTER)
+
+        trig_level50 = wx.Button (self, 1006, "50%")
+        trig_level50.SetToolTipString ("Set trigger level to 50%")
+        wx.EVT_BUTTON (self, 1006, self.set_trig_level50)
+        ctrlbox.Add (trig_level50, 0, wx.EXPAND)
+
+        run_stop = wx.Button (self, 1007, "Run/Stop")
+        run_stop.SetToolTipString ("Toggle Run/Stop mode")
+        wx.EVT_BUTTON (self, 1007, self.run_stop)
+        ctrlbox.Add (run_stop, 0, wx.EXPAND)
+
+        ctrlbox.Add ((10, 0) ,1)            # stretchy space
+
+        ctrlbox.Add (wx.StaticText (self, -1, "Fmt: "), 0, wx.ALIGN_CENTER)
+        self.marker_choice = wx.Choice (self, 1002, choices = 
self._marker_choices)
+        self.marker_choice.SetToolTipString ("Select plotting with lines, 
pluses or dots")
+        wx.EVT_CHOICE (self, 1002, self.marker_choice_event)
+        ctrlbox.Add (self.marker_choice, 0, wx.ALIGN_CENTER)
+
+        self.xy_choice = wx.Choice (self, 1003, choices = ['X:t', 'X:Y'])
+        self.xy_choice.SetToolTipString ("Select X vs time or X vs Y display")
+        wx.EVT_CHOICE (self, 1003, self.xy_choice_event)
+        ctrlbox.Add (self.xy_choice, 0, wx.ALIGN_CENTER)
+
+        return ctrlbox
+    
+    _marker_choices = ['line', 'plus', 'dot']
+
+    def update_timebase_label (self):
+        time_per_div = self.info.get_time_per_div ()
+        s = ' ' + eng_notation.num_to_str (time_per_div) + 's/div'
+        self.time_base_label.SetLabel (s)
+        
+    def decr_timebase (self, evt):
+        self.info.time_scale_cursor.prev ()
+        self.update_timebase_label ()
+
+    def incr_timebase (self, evt):
+        self.info.time_scale_cursor.next ()
+        self.update_timebase_label ()
+
+    def update_v_scale_label (self):
+        volts_per_div = self.info.get_volts_per_div ()
+        s = ' ' + eng_notation.num_to_str (volts_per_div) + '/div' # Not V/div
+        self.v_scale_label.SetLabel (s)
+        
+    def decr_v_scale (self, evt):
+        self.info.v_scale_cursor.prev ()
+        self.update_v_scale_label ()
+
+    def incr_v_scale (self, evt):
+        self.info.v_scale_cursor.next ()
+        self.update_v_scale_label ()
+        
+    def marker_choice_event (self, evt):
+        s = evt.GetString ()
+        self.set_marker (s)
+
+    def set_autorange(self, on):
+        if on:
+            self.v_scale_label.SetLabel(" (auto)")
+            self.info.autorange = True
+            self.autorange_checkbox.SetValue(True)
+            self.inc_v_button.Enable(False)
+            self.dec_v_button.Enable(False)
+        else:
+            if self.graph.y_range:
+                (l,u) = self.graph.y_range # found by autorange
+                self.info.v_scale_cursor.set_index_by_value((u-l)/8.0)
+            self.update_v_scale_label()
+            self.info.autorange = False
+            self.autorange_checkbox.SetValue(False)
+            self.inc_v_button.Enable(True)
+            self.dec_v_button.Enable(True)
+            
+    def autorange_checkbox_event(self, evt):
+        if evt.Checked():
+            self.set_autorange(True)
+        else:
+            self.set_autorange(False)
+            
+    def set_marker (self, s):
+        self.info.set_marker (s)        # set info for drawing routines
+        i = self.marker_choice.FindString (s)
+        assert i >= 0, "Hmmm, set_marker problem"
+        self.marker_choice.SetSelection (i)
+
+    def set_format_line (self):
+        self.set_marker ('line')
+
+    def set_format_dot (self):
+        self.set_marker ('dot')
+
+    def set_format_plus (self):
+        self.set_marker ('plus')
+        
+    def xy_choice_event (self, evt):
+        s = evt.GetString ()
+        self.info.xy = s == 'X:Y'
+
+    def trig_chan_choice_event (self, evt):
+        s = evt.GetString ()
+        ch = int (s[-1]) - 1
+        self.info.scopesink.set_trigger_channel (ch)
+
+    def trig_mode_choice_event (self, evt):
+        sink = self.info.scopesink
+        s = evt.GetString ()
+        if s == 'Pos':
+            sink.set_trigger_mode (gr.gr_TRIG_POS_SLOPE)
+        elif s == 'Neg':
+            sink.set_trigger_mode (gr.gr_TRIG_NEG_SLOPE)
+        elif s == 'Auto':
+            sink.set_trigger_mode (gr.gr_TRIG_AUTO)
+        else:
+            assert 0, "Bad trig_mode_choice string"
+    
+    def set_trig_level50 (self, evt):
+        self.info.scopesink.set_trigger_level_auto ()
+
+    def run_stop (self, evt):
+        self.info.running = not self.info.running
+        
+
+class graph_window (plot.PlotCanvas):
+
+    channel_colors = ['BLUE', 'RED',
+                      'CYAN', 'MAGENTA', 'GREEN', 'YELLOW']
+    
+    def __init__ (self, info, parent, id = -1,
+                  pos = wx.DefaultPosition, size = (640, 240),
+                  style = wx.DEFAULT_FRAME_STYLE, name = ""):
+        plot.PlotCanvas.__init__ (self, parent, id, pos, size, style, name)
+
+        self.SetXUseScopeTicks (True)
+        self.SetEnableGrid (True)
+        self.SetEnableZoom (True)
+        self.SetEnableLegend(True)
+        # self.SetBackgroundColour ('black')
+        
+        self.info = info;
+        self.y_range = None
+        self.x_range = None
+        self.avg_y_min = None
+        self.avg_y_max = None
+        self.avg_x_min = None
+        self.avg_x_max = None
+
+        EVT_DATA_EVENT (self, self.format_data)
+
+        self.input_watcher = input_watcher (info.msgq, self, info.frame_decim)
+
+    def channel_color (self, ch):
+        return self.channel_colors[ch % len(self.channel_colors)]
+       
+    def format_data (self, evt):
+        if not self.info.running:
+            return
+        
+        if self.info.xy:
+            self.format_xy_data (evt)
+            return
+
+        info = self.info
+        records = evt.data
+        nchannels = len (records)
+        npoints = len (records[0])
+
+        objects = []
+
+        Ts = 1.0 / (info.get_sample_rate () / info.get_decimation_rate ())
+        x_vals = Ts * numpy.arange (-npoints/2, npoints/2)
+
+        # preliminary clipping based on time axis here, instead of in graphics 
code
+        time_per_window = self.info.get_time_per_div () * 10
+        n = int (time_per_window / Ts + 0.5)
+        n = n & ~0x1                    # make even
+        n = max (2, min (n, npoints))
+
+        self.SetXUseScopeTicks (True)   # use 10 divisions, no labels
+
+        for ch in range(nchannels):
+            r = records[ch]
+
+            # plot middle n points of record
+
+            lb = npoints/2 - n/2
+            ub = npoints/2 + n/2
+            # points = zip (x_vals[lb:ub], r[lb:ub])
+            points = numpy.zeros ((ub-lb, 2), numpy.float64)
+            points[:,0] = x_vals[lb:ub]
+            points[:,1] = r[lb:ub]
+
+            m = info.get_marker ()
+            if m == 'line':
+                objects.append (plot.PolyLine (points,
+                                               colour=self.channel_color (ch),
+                                               legend=('Ch%d' % (ch+1,))))
+            else:
+                objects.append (plot.PolyMarker (points,
+                                                 marker=m,
+                                                 colour=self.channel_color 
(ch),
+                                                 legend=('Ch%d' % (ch+1,))))
+
+        graphics = plot.PlotGraphics (objects,
+                                      title=self.info.title,
+                                      xLabel = '', yLabel = '')
+
+        time_per_div = info.get_time_per_div ()
+        x_range = (-5.0 * time_per_div, 5.0 * time_per_div) # ranges are 
tuples!
+        volts_per_div = info.get_volts_per_div ()
+        if not self.info.autorange:
+            self.y_range = (-4.0 * volts_per_div, 4.0 * volts_per_div)
+        self.Draw (graphics, xAxis=x_range, yAxis=self.y_range)
+        self.update_y_range () # autorange to self.y_range
+
+
+    def format_xy_data (self, evt):
+        info = self.info
+        records = evt.data
+        nchannels = len (records)
+        npoints = len (records[0])
+
+        if nchannels < 2:
+            return
+
+        objects = []
+        # points = zip (records[0], records[1])
+        points = numpy.zeros ((len(records[0]), 2), numpy.float32)
+        points[:,0] = records[0]
+        points[:,1] = records[1]
+        
+        self.SetXUseScopeTicks (False)
+
+        m = info.get_marker ()
+        if m == 'line':
+            objects.append (plot.PolyLine (points,
+                                           colour=self.channel_color (0)))
+        else:
+            objects.append (plot.PolyMarker (points,
+                                             marker=m,
+                                             colour=self.channel_color (0)))
+
+        graphics = plot.PlotGraphics (objects,
+                                      title=self.info.title,
+                                      xLabel = 'I', yLabel = 'Q')
+
+        self.Draw (graphics, xAxis=self.x_range, yAxis=self.y_range)
+        self.update_y_range ()
+        self.update_x_range ()
+
+
+    def update_y_range (self):
+        alpha = 1.0/25
+        graphics = self.last_draw[0]
+        p1, p2 = graphics.boundingBox ()     # min, max points of graphics
+
+        if self.avg_y_min: # prevent vertical scale from jumping abruptly --?
+            self.avg_y_min = p1[1] * alpha + self.avg_y_min * (1 - alpha)
+            self.avg_y_max = p2[1] * alpha + self.avg_y_max * (1 - alpha)
+        else: # initial guess
+            self.avg_y_min = p1[1] # -500.0 workaround, sometimes p1 is ~ 10^35
+            self.avg_y_max = p2[1] # 500.0
+
+        self.y_range = self._axisInterval ('auto', self.avg_y_min, 
self.avg_y_max)
+        # print "p1 %s  p2 %s  y_min %s  y_max %s  y_range %s" \
+        #        % (p1, p2, self.avg_y_min, self.avg_y_max, self.y_range)
+
+
+    def update_x_range (self):
+        alpha = 1.0/25
+        graphics = self.last_draw[0]
+        p1, p2 = graphics.boundingBox ()     # min, max points of graphics
+
+        if self.avg_x_min:
+            self.avg_x_min = p1[0] * alpha + self.avg_x_min * (1 - alpha)
+            self.avg_x_max = p2[0] * alpha + self.avg_x_max * (1 - alpha)
+        else:
+            self.avg_x_min = p1[0]
+            self.avg_x_max = p2[0]
+
+        self.x_range = self._axisInterval ('auto', self.avg_x_min, 
self.avg_x_max)
+
+
+# ----------------------------------------------------------------
+# Stand-alone test application
+# ----------------------------------------------------------------
+
+class test_top_block (stdgui2.std_top_block):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv)
+
+        if len(argv) > 1:
+            frame_decim = int(argv[1]) 
+        else:
+            frame_decim = 1
+
+        if len(argv) > 2:
+            v_scale = float(argv[2])  # start up at this v_scale value
+        else:
+            v_scale = None  # start up in autorange mode, default
+
+        if len(argv) > 3:
+            t_scale = float(argv[3])  # start up at this t_scale value
+        else:
+            t_scale = None  # old behavior
+
+        print "frame decim %s  v_scale %s  t_scale %s" % 
(frame_decim,v_scale,t_scale)
+            
+        input_rate = 1e6
+
+        # Generate a complex sinusoid
+        self.src0 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 25.1e3, 1e3)
+
+        # We add this throttle block so that this demo doesn't suck down
+        # all the CPU available.  You normally wouldn't use it...
+        self.thr = gr.throttle(gr.sizeof_gr_complex, input_rate)
+
+        scope = scope_sink_c (panel,"Secret Data",sample_rate=input_rate,
+                              frame_decim=frame_decim,
+                              v_scale=v_scale, t_scale=t_scale)
+        vbox.Add (scope.win, 1, wx.EXPAND)
+
+        # Ultimately this will be
+        # self.connect("src0 throttle scope")
+       self.connect(self.src0, self.thr, scope) 
+
+def main ():
+    app = stdgui2.stdapp (test_top_block, "O'Scope Test App")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
+
+# ----------------------------------------------------------------


Property changes on: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/scopesink_nongl.py
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native


Property changes on: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/slider.py
___________________________________________________________________
Name: svn:executable
   - *

Modified: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/waterfallsink2.py
===================================================================
--- 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/waterfallsink2.py
    2008-08-14 16:19:53 UTC (rev 9286)
+++ 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/waterfallsink2.py
    2008-08-14 16:25:51 UTC (rev 9287)
@@ -24,12 +24,12 @@
 p = gr.prefs()
 style = p.get_string('wxgui', 'style', 'auto')
 
-# In 3.2 we'll change 'auto' to mean 'gl'
+# In 3.2 we'll change 'auto' to mean 'gl' if possible, then fallback
 if style == 'auto':
     style = 'nongl'
 
 if style == 'nongl':
-    from waterfallsink2_old import waterfall_sink_f, waterfall_sink_c
+    from waterfallsink_nongl import waterfall_sink_f, waterfall_sink_c
 elif style == 'gl':
     try:
         import wx

Deleted: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/waterfallsink2_old.py

Copied: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/waterfallsink_nongl.py
 (from rev 9284, 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/waterfallsink2_old.py)
===================================================================
--- 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/waterfallsink_nongl.py
                               (rev 0)
+++ 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/waterfallsink_nongl.py
       2008-08-14 16:25:51 UTC (rev 9287)
@@ -0,0 +1,437 @@
+#!/usr/bin/env python
+#
+# Copyright 2003,2004,2005,2007,2008 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, gru, window
+from gnuradio.wxgui import stdgui2
+import wx
+import gnuradio.wxgui.plot as plot
+import numpy
+import os
+import threading
+import math    
+
+default_fftsink_size = (640,240)
+default_fft_rate = gr.prefs().get_long('wxgui', 'fft_rate', 15)
+
+class waterfall_sink_base(object):
+    def __init__(self, input_is_real=False, baseband_freq=0,
+                 sample_rate=1, fft_size=512,
+                 fft_rate=default_fft_rate,
+                 average=False, avg_alpha=None, title=''):
+
+        # initialize common attributes
+        self.baseband_freq = baseband_freq
+        self.sample_rate = sample_rate
+        self.fft_size = fft_size
+        self.fft_rate = fft_rate
+        self.average = average
+        if avg_alpha is None:
+            self.avg_alpha = 2.0 / fft_rate
+        else:
+            self.avg_alpha = avg_alpha
+        self.title = title
+        self.input_is_real = input_is_real
+        self.msgq = gr.msg_queue(2)         # queue up to 2 messages
+
+    def set_average(self, average):
+        self.average = average
+        if average:
+            self.avg.set_taps(self.avg_alpha)
+        else:
+            self.avg.set_taps(1.0)
+
+    def set_avg_alpha(self, avg_alpha):
+        self.avg_alpha = avg_alpha
+
+    def set_baseband_freq(self, baseband_freq):
+        self.baseband_freq = baseband_freq
+
+    def set_sample_rate(self, sample_rate):
+        self.sample_rate = sample_rate
+        self._set_n()
+
+    def _set_n(self):
+        self.one_in_n.set_n(max(1, 
int(self.sample_rate/self.fft_size/self.fft_rate)))
+        
+class waterfall_sink_f(gr.hier_block2, waterfall_sink_base):
+    def __init__(self, parent, baseband_freq=0,
+                 y_per_div=10, ref_level=50, sample_rate=1, fft_size=512,
+                 fft_rate=default_fft_rate, average=False, avg_alpha=None,
+                 title='', size=default_fftsink_size):
+
+        gr.hier_block2.__init__(self, "waterfall_sink_f",
+                                gr.io_signature(1, 1, gr.sizeof_float),
+                                gr.io_signature(0,0,0))
+
+        waterfall_sink_base.__init__(self, input_is_real=True, 
baseband_freq=baseband_freq,
+                               sample_rate=sample_rate, fft_size=fft_size,
+                               fft_rate=fft_rate,
+                               average=average, avg_alpha=avg_alpha, 
title=title)
+                               
+        self.s2p = gr.serial_to_parallel(gr.sizeof_float, self.fft_size)
+        self.one_in_n = gr.keep_one_in_n(gr.sizeof_float * self.fft_size,
+                                         max(1, 
int(self.sample_rate/self.fft_size/self.fft_rate)))
+        
+        mywindow = window.blackmanharris(self.fft_size)
+        self.fft = gr.fft_vfc(self.fft_size, True, mywindow)
+        self.c2mag = gr.complex_to_mag(self.fft_size)
+        self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size)
+        self.log = gr.nlog10_ff(20, self.fft_size, 
-20*math.log10(self.fft_size))
+        self.sink = gr.message_sink(gr.sizeof_float * self.fft_size, 
self.msgq, True)
+       self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, 
self.avg, self.log, self.sink)
+
+        self.win = waterfall_window(self, parent, size=size)
+        self.set_average(self.average)
+
+
+class waterfall_sink_c(gr.hier_block2, waterfall_sink_base):
+    def __init__(self, parent, baseband_freq=0,
+                 y_per_div=10, ref_level=50, sample_rate=1, fft_size=512,
+                 fft_rate=default_fft_rate, average=False, avg_alpha=None, 
+                 title='', size=default_fftsink_size):
+
+        gr.hier_block2.__init__(self, "waterfall_sink_f",
+                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
+                                gr.io_signature(0,0,0))
+
+        waterfall_sink_base.__init__(self, input_is_real=False, 
baseband_freq=baseband_freq,
+                                     sample_rate=sample_rate, 
fft_size=fft_size,
+                                     fft_rate=fft_rate,
+                                     average=average, avg_alpha=avg_alpha, 
title=title)
+
+        self.s2p = gr.serial_to_parallel(gr.sizeof_gr_complex, self.fft_size)
+        self.one_in_n = gr.keep_one_in_n(gr.sizeof_gr_complex * self.fft_size,
+                                         max(1, 
int(self.sample_rate/self.fft_size/self.fft_rate)))
+        
+        mywindow = window.blackmanharris(self.fft_size)
+        self.fft = gr.fft_vcc(self.fft_size, True, mywindow)
+        self.c2mag = gr.complex_to_mag(self.fft_size)
+        self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size)
+        self.log = gr.nlog10_ff(20, self.fft_size, 
-20*math.log10(self.fft_size))
+        self.sink = gr.message_sink(gr.sizeof_float * self.fft_size, 
self.msgq, True)
+       self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, 
self.avg, self.log, self.sink)
+
+        self.win = waterfall_window(self, parent, size=size)
+        self.set_average(self.average)
+
+
+# ------------------------------------------------------------------------
+
+myDATA_EVENT = wx.NewEventType()
+EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0)
+
+
+class DataEvent(wx.PyEvent):
+    def __init__(self, data):
+        wx.PyEvent.__init__(self)
+        self.SetEventType (myDATA_EVENT)
+        self.data = data
+
+    def Clone (self): 
+        self.__class__ (self.GetId())
+
+
+class input_watcher (threading.Thread):
+    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 ()
+
+    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())
+
+            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]
+
+            complex_data = numpy.fromstring (s, numpy.float32)
+            de = DataEvent (complex_data)
+            wx.PostEvent (self.event_receiver, de)
+            del de
+    
+
+class waterfall_window (wx.Panel):
+    def __init__ (self, fftsink, parent, id = -1,
+                  pos = wx.DefaultPosition, size = wx.DefaultSize,
+                  style = wx.DEFAULT_FRAME_STYLE, name = ""):
+        wx.Panel.__init__(self, parent, id, pos, size, style, name)
+        self.set_baseband_freq = fftsink.set_baseband_freq
+        self.fftsink = fftsink
+        self.bm = wx.EmptyBitmap(self.fftsink.fft_size, 300, -1)
+
+        self.scale_factor = 5.0           # FIXME should autoscale, or set this
+        
+        dc1 = wx.MemoryDC()
+        dc1.SelectObject(self.bm)
+        dc1.Clear()
+
+        self.pens = self.make_pens()
+
+        wx.EVT_PAINT( self, self.OnPaint )
+        wx.EVT_CLOSE (self, self.on_close_window)
+        EVT_DATA_EVENT (self, self.set_data)
+        
+        self.build_popup_menu()
+        
+        wx.EVT_CLOSE (self, self.on_close_window)
+        self.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
+
+        self.input_watcher = input_watcher(fftsink.msgq, fftsink.fft_size, 
self)
+
+
+    def on_close_window (self, event):
+        print "waterfall_window: on_close_window"
+        self.keep_running = False
+
+    def const_list(self,const,len):
+        return [const] * len
+
+    def make_colormap(self):
+        r = []
+        r.extend(self.const_list(0,96))
+        r.extend(range(0,255,4))
+        r.extend(self.const_list(255,64))
+        r.extend(range(255,128,-4))
+        
+        g = []
+        g.extend(self.const_list(0,32))
+        g.extend(range(0,255,4))
+        g.extend(self.const_list(255,64))
+        g.extend(range(255,0,-4))
+        g.extend(self.const_list(0,32))
+        
+        b = range(128,255,4)
+        b.extend(self.const_list(255,64))
+        b.extend(range(255,0,-4))
+        b.extend(self.const_list(0,96))
+        return (r,g,b)
+
+    def make_pens(self):
+        (r,g,b) = self.make_colormap()
+        pens = []
+        for i in range(0,256):
+            colour = wx.Colour(r[i], g[i], b[i])
+            pens.append( wx.Pen(colour, 2, wx.SOLID))
+        return pens
+        
+    def OnPaint(self, event):
+        dc = wx.PaintDC(self)
+        self.DoDrawing(dc)
+
+    def DoDrawing(self, dc=None):
+        if dc is None:
+            dc = wx.ClientDC(self)
+        dc.DrawBitmap(self.bm, 0, 0, False )
+    
+
+    def const_list(self,const,len):
+        a = [const]
+        for i in range(1,len):
+            a.append(const)
+        return a
+
+
+    def set_data (self, evt):
+        dB = evt.data
+        L = len (dB)
+
+        dc1 = wx.MemoryDC()
+        dc1.SelectObject(self.bm)
+        dc1.Blit(0,1,self.fftsink.fft_size,300,dc1,0,0,wx.COPY,False,-1,-1)
+
+        x = max(abs(self.fftsink.sample_rate), abs(self.fftsink.baseband_freq))
+        if x >= 1e9:
+            sf = 1e-9
+            units = "GHz"
+        elif x >= 1e6:
+            sf = 1e-6
+            units = "MHz"
+        else:
+            sf = 1e-3
+            units = "kHz"
+
+
+        if self.fftsink.input_is_real:     # only plot 1/2 the points
+            d_max = L/2
+            p_width = 2
+        else:
+            d_max = L/2
+            p_width = 1
+
+        scale_factor = self.scale_factor
+        if self.fftsink.input_is_real:     # real fft
+           for x_pos in range(0, d_max):
+               value = int(dB[x_pos] * scale_factor)
+               value = min(255, max(0, value))
+               dc1.SetPen(self.pens[value])
+               dc1.DrawRectangle(x_pos*p_width, 0, p_width, 2) 
+        else:                               # complex fft
+           for x_pos in range(0, d_max):    # positive freqs
+               value = int(dB[x_pos] * scale_factor)
+               value = min(255, max(0, value))
+               dc1.SetPen(self.pens[value])
+               dc1.DrawRectangle(x_pos*p_width + d_max, 0, p_width, 2) 
+           for x_pos in range(0 , d_max):   # negative freqs
+               value = int(dB[x_pos+d_max] * scale_factor)
+               value = min(255, max(0, value))
+               dc1.SetPen(self.pens[value])
+               dc1.DrawRectangle(x_pos*p_width, 0, p_width, 2) 
+
+       del dc1
+        self.DoDrawing (None)
+
+    def on_average(self, evt):
+        # print "on_average"
+        self.fftsink.set_average(evt.IsChecked())
+
+    def on_right_click(self, event):
+        menu = self.popup_menu
+        for id, pred in self.checkmarks.items():
+            item = menu.FindItemById(id)
+            item.Check(pred())
+        self.PopupMenu(menu, event.GetPosition())
+
+
+    def build_popup_menu(self):
+        self.id_incr_ref_level = wx.NewId()
+        self.id_decr_ref_level = wx.NewId()
+        self.id_incr_y_per_div = wx.NewId()
+        self.id_decr_y_per_div = wx.NewId()
+        self.id_y_per_div_1 = wx.NewId()
+        self.id_y_per_div_2 = wx.NewId()
+        self.id_y_per_div_5 = wx.NewId()
+        self.id_y_per_div_10 = wx.NewId()
+        self.id_y_per_div_20 = wx.NewId()
+        self.id_average = wx.NewId()
+
+        self.Bind(wx.EVT_MENU, self.on_average, id=self.id_average)
+        #self.Bind(wx.EVT_MENU, self.on_incr_ref_level, 
id=self.id_incr_ref_level)
+        #self.Bind(wx.EVT_MENU, self.on_decr_ref_level, 
id=self.id_decr_ref_level)
+        #self.Bind(wx.EVT_MENU, self.on_incr_y_per_div, 
id=self.id_incr_y_per_div)
+        #self.Bind(wx.EVT_MENU, self.on_decr_y_per_div, 
id=self.id_decr_y_per_div)
+        #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_1)
+        #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_2)
+        #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_5)
+        #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_10)
+        #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_20)
+
+
+        # make a menu
+        menu = wx.Menu()
+        self.popup_menu = menu
+        menu.AppendCheckItem(self.id_average, "Average")
+        # menu.Append(self.id_incr_ref_level, "Incr Ref Level")
+        # menu.Append(self.id_decr_ref_level, "Decr Ref Level")
+        # menu.Append(self.id_incr_y_per_div, "Incr dB/div")
+        # menu.Append(self.id_decr_y_per_div, "Decr dB/div")
+        # menu.AppendSeparator()
+        # we'd use RadioItems for these, but they're not supported on Mac
+        #menu.AppendCheckItem(self.id_y_per_div_1, "1 dB/div")
+        #menu.AppendCheckItem(self.id_y_per_div_2, "2 dB/div")
+        #menu.AppendCheckItem(self.id_y_per_div_5, "5 dB/div")
+        #menu.AppendCheckItem(self.id_y_per_div_10, "10 dB/div")
+        #menu.AppendCheckItem(self.id_y_per_div_20, "20 dB/div")
+
+        self.checkmarks = {
+            self.id_average : lambda : self.fftsink.average
+            #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,
+            #self.id_y_per_div_5 : lambda : self.fftsink.y_per_div == 5,
+            #self.id_y_per_div_10 : lambda : self.fftsink.y_per_div == 10,
+            #self.id_y_per_div_20 : lambda : self.fftsink.y_per_div == 20,
+            }
+
+
+def next_up(v, seq):
+    """
+    Return the first item in seq that is > v.
+    """
+    for s in seq:
+        if s > v:
+            return s
+    return v
+
+def next_down(v, seq):
+    """
+    Return the last item in seq that is < v.
+    """
+    rseq = list(seq[:])
+    rseq.reverse()
+
+    for s in rseq:
+        if s < v:
+            return s
+    return v
+
+
+# ----------------------------------------------------------------
+# Standalone test app
+# ----------------------------------------------------------------
+
+class test_top_block (stdgui2.std_top_block):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv)
+
+        fft_size = 512
+
+        # build our flow graph
+        input_rate = 20.000e3
+
+        # Generate a complex sinusoid
+        self.src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000)
+        #src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1000)
+
+        # We add these throttle blocks so that this demo doesn't
+        # suck down all the CPU available.  Normally you wouldn't use these.
+        self.thr1 = gr.throttle(gr.sizeof_gr_complex, input_rate)
+
+        sink1 = waterfall_sink_c (panel, title="Complex Data", 
fft_size=fft_size,
+                                  sample_rate=input_rate, baseband_freq=100e3)
+       self.connect(self.src1, self.thr1, sink1)
+        vbox.Add (sink1.win, 1, wx.EXPAND)
+
+        # generate a real sinusoid
+        self.src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000)
+        self.thr2 = gr.throttle(gr.sizeof_float, input_rate)
+        sink2 = waterfall_sink_f (panel, title="Real Data", fft_size=fft_size,
+                                  sample_rate=input_rate, baseband_freq=100e3)
+       self.connect(self.src2, self.thr2, sink2)
+        vbox.Add (sink2.win, 1, wx.EXPAND)
+
+
+def main ():
+    app = stdgui2.stdapp (test_top_block, "Waterfall Sink Test App")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()


Property changes on: 
gnuradio/branches/developers/jblum/glwxgui/gr-wxgui/src/python/waterfallsink_nongl.py
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native





reply via email to

[Prev in Thread] Current Thread [Next in Thread]