summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gr-qtgui/apps/CMakeLists.txt8
-rwxr-xr-xgr-qtgui/apps/gr_constellation_plot75
-rwxr-xr-xgr-qtgui/apps/gr_psd_plot_b160
-rwxr-xr-xgr-qtgui/apps/gr_psd_plot_c145
-rwxr-xr-xgr-qtgui/apps/gr_psd_plot_f151
-rwxr-xr-xgr-qtgui/apps/gr_psd_plot_i157
-rwxr-xr-xgr-qtgui/apps/gr_psd_plot_s157
-rwxr-xr-xgr-qtgui/apps/gr_spectrogram_plot_b158
-rwxr-xr-xgr-qtgui/apps/gr_spectrogram_plot_c147
-rwxr-xr-xgr-qtgui/apps/gr_spectrogram_plot_f147
-rwxr-xr-xgr-qtgui/apps/gr_spectrogram_plot_i158
-rwxr-xr-xgr-qtgui/apps/gr_spectrogram_plot_s156
-rwxr-xr-xgr-qtgui/apps/gr_time_plot_b149
-rwxr-xr-xgr-qtgui/apps/gr_time_plot_c141
-rwxr-xr-xgr-qtgui/apps/gr_time_plot_f140
-rwxr-xr-xgr-qtgui/apps/gr_time_plot_i147
-rwxr-xr-xgr-qtgui/apps/gr_time_plot_s146
-rw-r--r--gr-qtgui/apps/plot_base.py156
-rw-r--r--gr-qtgui/apps/plot_constellation_form.py64
-rw-r--r--gr-qtgui/apps/plot_form.py319
-rw-r--r--gr-qtgui/apps/plot_psd_base.py163
-rw-r--r--gr-qtgui/apps/plot_psd_form.py98
-rw-r--r--gr-qtgui/apps/plot_spectrogram_base.py168
-rw-r--r--gr-qtgui/apps/plot_spectrogram_form.py164
-rw-r--r--gr-qtgui/apps/plot_time_base.py184
-rw-r--r--gr-qtgui/apps/plot_time_form.py79
-rwxr-xr-xgr-qtgui/examples/pyqt_waterfall_c.py10
-rwxr-xr-xgr-qtgui/examples/pyqt_waterfall_f.py5
-rw-r--r--gr-qtgui/include/qtgui/const_sink_c.h19
-rw-r--r--gr-qtgui/include/qtgui/freq_sink_c.h22
-rw-r--r--gr-qtgui/include/qtgui/freq_sink_f.h21
-rw-r--r--gr-qtgui/include/qtgui/time_sink_c.h19
-rw-r--r--gr-qtgui/include/qtgui/time_sink_f.h19
-rw-r--r--gr-qtgui/include/qtgui/waterfall_sink_c.h30
-rw-r--r--gr-qtgui/include/qtgui/waterfall_sink_f.h30
-rw-r--r--gr-qtgui/lib/DisplayPlot.cc2
-rw-r--r--gr-qtgui/lib/DisplayPlot.h3
-rw-r--r--gr-qtgui/lib/FrequencyDisplayPlot.cc6
-rw-r--r--gr-qtgui/lib/TimeDomainDisplayPlot.cc18
-rw-r--r--gr-qtgui/lib/TimeDomainDisplayPlot.h2
-rw-r--r--gr-qtgui/lib/WaterfallDisplayPlot.cc75
-rw-r--r--gr-qtgui/lib/WaterfallDisplayPlot.h6
-rw-r--r--gr-qtgui/lib/const_sink_c_impl.cc63
-rw-r--r--gr-qtgui/lib/const_sink_c_impl.h14
-rw-r--r--gr-qtgui/lib/displayform.cc52
-rw-r--r--gr-qtgui/lib/displayform.h11
-rw-r--r--gr-qtgui/lib/form_menus.h78
-rw-r--r--gr-qtgui/lib/freq_sink_c_impl.cc86
-rw-r--r--gr-qtgui/lib/freq_sink_c_impl.h18
-rw-r--r--gr-qtgui/lib/freq_sink_f_impl.cc84
-rw-r--r--gr-qtgui/lib/freq_sink_f_impl.h17
-rw-r--r--gr-qtgui/lib/freqdisplayform.cc2
-rw-r--r--gr-qtgui/lib/time_sink_c_impl.cc75
-rw-r--r--gr-qtgui/lib/time_sink_c_impl.h18
-rw-r--r--gr-qtgui/lib/time_sink_f_impl.cc75
-rw-r--r--gr-qtgui/lib/time_sink_f_impl.h16
-rw-r--r--gr-qtgui/lib/timedisplayform.cc14
-rw-r--r--gr-qtgui/lib/timedisplayform.h3
-rw-r--r--gr-qtgui/lib/waterfall_sink_c_impl.cc103
-rw-r--r--gr-qtgui/lib/waterfall_sink_c_impl.h26
-rw-r--r--gr-qtgui/lib/waterfall_sink_f_impl.cc100
-rw-r--r--gr-qtgui/lib/waterfall_sink_f_impl.h32
-rw-r--r--gr-qtgui/lib/waterfalldisplayform.cc80
-rw-r--r--gr-qtgui/lib/waterfalldisplayform.h18
-rw-r--r--gr-qtgui/swig/CMakeLists.txt1
-rw-r--r--gr-qtgui/swig/qtgui_swig.i4
66 files changed, 2902 insertions, 2112 deletions
diff --git a/gr-qtgui/apps/CMakeLists.txt b/gr-qtgui/apps/CMakeLists.txt
index 07a8298701..dcce338779 100644
--- a/gr-qtgui/apps/CMakeLists.txt
+++ b/gr-qtgui/apps/CMakeLists.txt
@@ -21,7 +21,15 @@ include(GrPython)
GR_PYTHON_INSTALL(
FILES
+ plot_base.py
+ plot_psd_base.py
+ plot_spectrogram_base.py
+ plot_time_base.py
plot_form.py
+ plot_constellation_form.py
+ plot_psd_form.py
+ plot_spectrogram_form.py
+ plot_time_form.py
DESTINATION ${GR_PYTHON_DIR}/gnuradio/qtgui
COMPONENT "qtgui_python"
)
diff --git a/gr-qtgui/apps/gr_constellation_plot b/gr-qtgui/apps/gr_constellation_plot
index 02805a8fd1..92c4e3be15 100755
--- a/gr-qtgui/apps/gr_constellation_plot
+++ b/gr-qtgui/apps/gr_constellation_plot
@@ -40,37 +40,30 @@ except ImportError:
sys.exit(1)
try:
- from gnuradio.qtgui.plot_form import *
+ from gnuradio.qtgui.plot_constellation_form import *
+ from gnuradio.qtgui.plot_base import *
except ImportError:
- from plot_form import *
-
-def read_samples(filename, start, in_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_gr_complex, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.complex64, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- if(len(data) < in_size):
- print "Warning: read in {0} samples but asked for {1} samples.".format(
- len(data), in_size)
-
- return data
+ from plot_constellation_form import *
+ from plot_base import *
class my_top_block(gr.top_block):
def __init__(self, filelist, start, nsamples, max_nsamples):
gr.top_block.__init__(self)
self._filelist = filelist
+ self._samp_rate = 0
+ self._center_freq = 0
self._start = start
self._max_nsamps = max_nsamples
self._nsigs = len(self._filelist)
+ self._nsamps = nsamples
+ self._auto_scale = True
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
+ self._y_min = -20
+ self._y_max = 20
+ self._y_range = 4
+ self._y_value = 2
+ self.gui_y_axis = None
self.qapp = QtGui.QApplication(sys.argv)
@@ -80,10 +73,17 @@ class my_top_block(gr.top_block):
self._nsigs)
n = 0
self.srcs = list()
+ self._data_min = sys.maxint
+ self._data_max = -sys.maxint - 1
for f in filelist:
- data = read_samples(f, self._start, self._nsamps)
+ data,_min,_max = read_samples_c(f, self._start, self._nsamps)
self.srcs.append(gr.vector_source_c(data))
+ if(_min < self._data_min):
+ self._data_min = _min
+ if(_max > self._data_max):
+ self._data_max = _max
+
# Set default labels based on file names
fname = f.split("/")[-1]
self.gui_snk.set_line_label(n, "{0}".format(fname))
@@ -95,6 +95,8 @@ class my_top_block(gr.top_block):
for i,s in enumerate(self.srcs[1:]):
self.connect(s, (self.gui_snk, i+1))
+ self.gui_snk.enable_menu(False)
+
# Get Python Qt references
pyQt = self.gui_snk.pyqwidget()
self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
@@ -109,7 +111,7 @@ class my_top_block(gr.top_block):
self._start = newstart
for s,f in zip(self.srcs, self._filelist):
- data = read_samples(f, self._start, newnsamps)
+ data,_min,_max = read_samples_c(f, self._start, newnsamps)
s.set_data(data)
if(len(data) < newnsamps):
newnsamps = len(data)
@@ -119,12 +121,33 @@ class my_top_block(gr.top_block):
self.start()
+ def set_y_axis(self, y_min, y_max):
+ y_min = -y_max
+ self.gui_snk.set_y_axis(y_min, y_max)
+ self.gui_snk.set_x_axis(y_min, y_max)
+ return y_min, y_max
+
+ def auto_scale(self, state):
+ if(state > 0):
+ self.set_y_axis(self._data_min, self._data_max)
+ self._auto_scale = True
+ self._y_value = self._data_max
+ self._y_range = self._data_max - self._data_min
+ self._y_min = 10*self._data_min
+ self._y_max = 10*self._data_max
+
+ if(self.gui_y_axis):
+ self.gui_y_axis(self._data_min, self._data_max)
+ else:
+ self._auto_scale = False
+
+
def main():
description = "Plots the constellations of a list of files."
parser = OptionParser(option_class=eng_option, description=description,
conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
+ parser.add_option("-N", "--nsamples", type="int", default=1000000,
+ help="Set the number of samples to display [default=%default]")
parser.add_option("-S", "--start", type="int", default=0,
help="Starting sample number [default=%default]")
(options, args) = parser.parse_args()
@@ -148,7 +171,9 @@ def main():
tb = my_top_block(filelist,
options.start, nsamples, max_nsamples);
- main_box = dialog_box(tb, 'GNU Radio Constellation Plot')
+ main_box = plot_constellation_form(tb, 'GNU Radio Constellation Plot')
+ for n in xrange(tb._nsigs):
+ main_box._style_edit[n].setCurrentIndex(0)
main_box.show()
tb.run()
diff --git a/gr-qtgui/apps/gr_psd_plot_b b/gr-qtgui/apps/gr_psd_plot_b
index b5d2104da2..d2c170a1d0 100755
--- a/gr-qtgui/apps/gr_psd_plot_b
+++ b/gr-qtgui/apps/gr_psd_plot_b
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,10 +21,12 @@
#
from gnuradio import gr
-from gnuradio import blocks
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_psd_base as plot_base
+except ImportError:
+ import plot_psd_base as plot_base
try:
from gnuradio import qtgui
@@ -34,144 +36,35 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples_and_pad(filename, start, in_size, min_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_char, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.uint8, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- # If we have to, append 0's to create min_size samples of data
- if(len(data) < min_size):
- data += (min_size - len(data)) * [scipy.uint8(0)]
-
- return data
-
-class my_top_block(gr.top_block):
+class psd_plot_b(plot_base.plot_base):
def __init__(self, filelist, fc, samp_rate, psdsize, start,
- nsamples, max_nsamples, scale, avg=1.0):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._center_freq = fc
- self._samp_rate = samp_rate
- self._psd_size = psdsize
- self._start = start
- self._max_nsamps = max_nsamples
- self._scale = scale
- self._nsigs = len(self._filelist)
- self._avg = avg
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_float, self._start)
+ nsamples, max_nsamples, avg=1.0, auto_scale=True):
+ plot_base.plot_base.__init__(self, filelist, fc, samp_rate,
+ psdsize, start, nsamples,
+ max_nsamples, avg)
+
+ self.read_samples = plot_base.read_samples_b
+ self.dsize = gr.sizeof_float
+ self.src_type = plot_base.source_chars_to_float
self.gui_snk = qtgui.freq_sink_f(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS,
self._center_freq, self._samp_rate,
"GNU Radio PSD Plot", self._nsigs)
- n = 0
- self.srcs = list()
- self.cnvrt = list()
- for f in filelist:
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- self.srcs.append(gr.vector_source_b(data))
- self.cnvrt.append(blocks.char_to_float(1, self._scale))
-
- # Set default labels based on file names
- fname = f.split("/")[-1]
- self.gui_snk.set_line_label(n, "{0}".format(fname))
- n += 1
-
- self.connect(self.srcs[0], self.cnvrt[0], self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs[1:]):
- self.connect(s, self.cnvrt[i], (self.gui_snk, i+1))
-
- self.gui_snk.set_update_time(0);
- self.gui_snk.set_fft_average(self._avg)
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
- self._nsamps = newnsamps
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- s.set_data(data)
-
- self.start()
+ self.setup()
def main():
- description = "Plots the PSDs of a list of files. Files are a binary list of chars/bytes."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-L", "--psd-size", type="int", default=2048,
- help="Set the FFT size of the PSD [default=%default]")
- parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0,
- help="Set the center frequency of the signal [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-a", "--average", type="float", default=1.0,
- help="Set amount of averaging (smaller=more averaging) [default=%default]")
- parser.add_option("-s", "--scale", type="eng_float", default=2**(8-1)-1,
- help="Set a scaling factor for the char->float conversion [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ description = "Plots the PSDs of a list of files. Files are a binary list of bytes."
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_char)
- max_nsamples = min(filesizes)
-
- tb = my_top_block(filelist,
- options.center_frequency, options.sample_rate,
- options.psd_size,
- options.start, nsamples, max_nsamples,
- options.scale, options.average)
+ tb = psd_plot_b(filelist,
+ options.center_frequency, options.sample_rate,
+ options.psd_size,
+ options.start, options.nsamples, max_nsamples,
+ options.average)
- main_box = dialog_box(tb, 'GNU Radio PSD Plot')
+ main_box = plot_base.plot_psd_form(tb, 'GNU Radio PSD Plot')
main_box.show()
tb.run()
@@ -182,4 +75,3 @@ if __name__ == "__main__":
main()
except KeyboardInterrupt:
pass
-
diff --git a/gr-qtgui/apps/gr_psd_plot_c b/gr-qtgui/apps/gr_psd_plot_c
index 0f7f4b9bef..06821d6934 100755
--- a/gr-qtgui/apps/gr_psd_plot_c
+++ b/gr-qtgui/apps/gr_psd_plot_c
@@ -21,9 +21,12 @@
#
from gnuradio import gr
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_psd_base as plot_base
+except ImportError:
+ import plot_psd_base as plot_base
try:
from gnuradio import qtgui
@@ -33,139 +36,35 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples_and_pad(filename, start, in_size, min_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_gr_complex, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.complex64, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- # If we have to, append 0's to create min_size samples of data
- if(len(data) < min_size):
- data += (min_size - len(data)) * [complex(0,0)]
-
- return data
-
-class my_top_block(gr.top_block):
+class psd_plot_c(plot_base.plot_base):
def __init__(self, filelist, fc, samp_rate, psdsize, start,
nsamples, max_nsamples, avg=1.0):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._center_freq = fc
- self._samp_rate = samp_rate
- self._psd_size = psdsize
- self._start = start
- self._max_nsamps = max_nsamples
- self._nsigs = len(self._filelist)
- self._avg = avg
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
+ plot_base.plot_base.__init__(self, filelist, fc, samp_rate,
+ psdsize, start, nsamples,
+ max_nsamples, avg)
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_gr_complex, self._start)
+ self.read_samples = plot_base.read_samples_c
+ self.dsize = gr.sizeof_gr_complex
+ self.src_type = gr.vector_source_c
self.gui_snk = qtgui.freq_sink_c(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS,
self._center_freq, self._samp_rate,
"GNU Radio PSD Plot", self._nsigs)
- n = 0
- self.srcs = list()
- for f in filelist:
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- self.srcs.append(gr.vector_source_c(data))
-
- # Set default labels based on file names
- fname = f.split("/")[-1]
- self.gui_snk.set_line_label(n, "{0}".format(fname))
- n += 1
-
- self.connect(self.srcs[0], self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs[1:]):
- self.connect(s, (self.gui_snk, i+1))
-
- self.gui_snk.set_update_time(0);
- self.gui_snk.set_fft_average(self._avg)
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
- self._nsamps = newnsamps
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- s.set_data(data)
-
- self.start()
+ self.setup()
def main():
description = "Plots the PSDs of a list of files. Files are a binary list of complex floats."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-L", "--psd-size", type="int", default=2048,
- help="Set the FFT size of the PSD [default=%default]")
- parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0,
- help="Set the center frequency of the signal [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-a", "--average", type="float", default=1.0,
- help="Set amount of averaging (smaller=more averaging) [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_gr_complex)
- max_nsamples = min(filesizes)
-
- tb = my_top_block(filelist,
- options.center_frequency, options.sample_rate,
- options.psd_size,
- options.start, nsamples, max_nsamples,
- options.average);
+ tb = psd_plot_c(filelist,
+ options.center_frequency, options.sample_rate,
+ options.psd_size,
+ options.start, options.nsamples, max_nsamples,
+ options.average)
- main_box = dialog_box(tb, 'GNU Radio PSD Plot')
+ main_box = plot_base.plot_psd_form(tb, 'GNU Radio PSD Plot')
main_box.show()
tb.run()
diff --git a/gr-qtgui/apps/gr_psd_plot_f b/gr-qtgui/apps/gr_psd_plot_f
index 973f7b29d9..1a6fd5b3d9 100755
--- a/gr-qtgui/apps/gr_psd_plot_f
+++ b/gr-qtgui/apps/gr_psd_plot_f
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,9 +21,12 @@
#
from gnuradio import gr
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_psd_base as plot_base
+except ImportError:
+ import plot_psd_base as plot_base
try:
from gnuradio import qtgui
@@ -33,139 +36,35 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples_and_pad(filename, start, in_size, min_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_float, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.float32, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- # If we have to, append 0's to create min_size samples of data
- if(len(data) < min_size):
- data += (min_size - len(data)) * [scipy.float32(0.0)]
-
- return data
-
-class my_top_block(gr.top_block):
+class psd_plot_f(plot_base.plot_base):
def __init__(self, filelist, fc, samp_rate, psdsize, start,
- nsamples, max_nsamples, avg=1.0):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._center_freq = fc
- self._samp_rate = samp_rate
- self._psd_size = psdsize
- self._start = start
- self._max_nsamps = max_nsamples
- self._nsigs = len(self._filelist)
- self._avg = avg
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_float, self._start)
+ nsamples, max_nsamples, avg=1.0, auto_scale=True):
+ plot_base.plot_base.__init__(self, filelist, fc, samp_rate,
+ psdsize, start, nsamples,
+ max_nsamples, avg)
+
+ self.read_samples = plot_base.read_samples_f
+ self.dsize = gr.sizeof_float
+ self.src_type = gr.vector_source_f
self.gui_snk = qtgui.freq_sink_f(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS,
self._center_freq, self._samp_rate,
"GNU Radio PSD Plot", self._nsigs)
- n = 0
- self.srcs = list()
- for f in filelist:
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- self.srcs.append(gr.vector_source_f(data))
-
- # Set default labels based on file names
- fname = f.split("/")[-1]
- self.gui_snk.set_line_label(n, "{0}".format(fname))
- n += 1
-
- self.connect(self.srcs[0], self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs[1:]):
- self.connect(s, (self.gui_snk, i+1))
-
- self.gui_snk.set_update_time(0);
- self.gui_snk.set_fft_average(self._avg)
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
- self._nsamps = newnsamps
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- s.set_data(data)
-
- self.start()
+ self.setup()
def main():
description = "Plots the PSDs of a list of files. Files are a binary list of floats."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-L", "--psd-size", type="int", default=2048,
- help="Set the FFT size of the PSD [default=%default]")
- parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0,
- help="Set the center frequency of the signal [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-a", "--average", type="float", default=1.0,
- help="Set amount of averaging (smaller=more averaging) [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_float)
- max_nsamples = min(filesizes)
-
- tb = my_top_block(filelist,
- options.center_frequency, options.sample_rate,
- options.psd_size,
- options.start, nsamples, max_nsamples,
- options.average);
+ tb = psd_plot_f(filelist,
+ options.center_frequency, options.sample_rate,
+ options.psd_size,
+ options.start, options.nsamples, max_nsamples,
+ options.average)
- main_box = dialog_box(tb, 'GNU Radio PSD Plot')
+ main_box = plot_base.plot_psd_form(tb, 'GNU Radio PSD Plot')
main_box.show()
tb.run()
diff --git a/gr-qtgui/apps/gr_psd_plot_i b/gr-qtgui/apps/gr_psd_plot_i
index f27011be22..c11a37fbbe 100755
--- a/gr-qtgui/apps/gr_psd_plot_i
+++ b/gr-qtgui/apps/gr_psd_plot_i
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,10 +21,12 @@
#
from gnuradio import gr
-from gnuradio import blocks
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_psd_base as plot_base
+except ImportError:
+ import plot_psd_base as plot_base
try:
from gnuradio import qtgui
@@ -34,144 +36,35 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples_and_pad(filename, start, in_size, min_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_int, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.int32, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- # If we have to, append 0's to create min_size samples of data
- if(len(data) < min_size):
- data += (min_size - len(data)) * [scipy.int32(0)]
-
- return data
-
-class my_top_block(gr.top_block):
+class psd_plot_i(plot_base.plot_base):
def __init__(self, filelist, fc, samp_rate, psdsize, start,
- nsamples, max_nsamples, scale, avg=1.0):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._center_freq = fc
- self._samp_rate = samp_rate
- self._psd_size = psdsize
- self._start = start
- self._max_nsamps = max_nsamples
- self._scale = scale
- self._nsigs = len(self._filelist)
- self._avg = avg
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_float, self._start)
+ nsamples, max_nsamples, avg=1.0, auto_scale=True):
+ plot_base.plot_base.__init__(self, filelist, fc, samp_rate,
+ psdsize, start, nsamples,
+ max_nsamples, avg)
+
+ self.read_samples = plot_base.read_samples_i
+ self.dsize = gr.sizeof_float
+ self.src_type = plot_base.source_ints_to_float
self.gui_snk = qtgui.freq_sink_f(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS,
self._center_freq, self._samp_rate,
"GNU Radio PSD Plot", self._nsigs)
- n = 0
- self.srcs = list()
- self.cnvrt = list()
- for f in filelist:
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- self.srcs.append(gr.vector_source_i(data))
- self.cnvrt.append(blocks.int_to_float(1, self._scale))
-
- # Set default labels based on file names
- fname = f.split("/")[-1]
- self.gui_snk.set_line_label(n, "{0}".format(fname))
- n += 1
-
- self.connect(self.srcs[0], self.cnvrt[0], self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs[1:]):
- self.connect(s, self.cnvrt[i], (self.gui_snk, i+1))
-
- self.gui_snk.set_update_time(0);
- self.gui_snk.set_fft_average(self._avg)
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
- self._nsamps = newnsamps
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- s.set_data(data)
-
- self.start()
+ self.setup()
def main():
description = "Plots the PSDs of a list of files. Files are a binary list of integers."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-L", "--psd-size", type="int", default=2048,
- help="Set the FFT size of the PSD [default=%default]")
- parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0,
- help="Set the center frequency of the signal [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-a", "--average", type="float", default=1.0,
- help="Set amount of averaging (smaller=more averaging) [default=%default]")
- parser.add_option("-s", "--scale", type="eng_float", default=2**(32-1)-1,
- help="Set a scaling factor for the int->float conversion [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_int)
- max_nsamples = min(filesizes)
-
- tb = my_top_block(filelist,
- options.center_frequency, options.sample_rate,
- options.psd_size,
- options.start, nsamples, max_nsamples,
- options.scale, options.average)
+ tb = psd_plot_i(filelist,
+ options.center_frequency, options.sample_rate,
+ options.psd_size,
+ options.start, options.nsamples, max_nsamples,
+ options.average)
- main_box = dialog_box(tb, 'GNU Radio PSD Plot')
+ main_box = plot_base.plot_psd_form(tb, 'GNU Radio PSD Plot')
main_box.show()
tb.run()
diff --git a/gr-qtgui/apps/gr_psd_plot_s b/gr-qtgui/apps/gr_psd_plot_s
index cd2d4a516e..f2da12fc96 100755
--- a/gr-qtgui/apps/gr_psd_plot_s
+++ b/gr-qtgui/apps/gr_psd_plot_s
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,9 +21,12 @@
#
from gnuradio import gr
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_psd_base as plot_base
+except ImportError:
+ import plot_psd_base as plot_base
try:
from gnuradio import qtgui
@@ -33,144 +36,35 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples_and_pad(filename, start, in_size, min_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_short, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.int16, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- # If we have to, append 0's to create min_size samples of data
- if(len(data) < min_size):
- data += (min_size - len(data)) * [scipy.int16(0)]
-
- return data
-
-class my_top_block(gr.top_block):
+class psd_plot_s(plot_base.plot_base):
def __init__(self, filelist, fc, samp_rate, psdsize, start,
- nsamples, max_nsamples, scale, avg=1.0):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._center_freq = fc
- self._samp_rate = samp_rate
- self._psd_size = psdsize
- self._start = start
- self._max_nsamps = max_nsamples
- self._scale = scale
- self._nsigs = len(self._filelist)
- self._avg = avg
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_float, self._start)
+ nsamples, max_nsamples, avg=1.0, auto_scale=True):
+ plot_base.plot_base.__init__(self, filelist, fc, samp_rate,
+ psdsize, start, nsamples,
+ max_nsamples, avg)
+
+ self.read_samples = plot_base.read_samples_s
+ self.dsize = gr.sizeof_float
+ self.src_type = plot_base.source_shorts_to_float
self.gui_snk = qtgui.freq_sink_f(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS,
self._center_freq, self._samp_rate,
"GNU Radio PSD Plot", self._nsigs)
- n = 0
- self.srcs = list()
- self.cnvrt = list()
- for f in filelist:
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- self.srcs.append(gr.vector_source_s(data))
- self.cnvrt.append(blocks.short_to_float(1, self._scale))
-
- # Set default labels based on file names
- fname = f.split("/")[-1]
- self.gui_snk.set_line_label(n, "{0}".format(fname))
- n += 1
-
- self.connect(self.srcs[0], self.cnvrt[0], self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs[1:]):
- self.connect(s, self.cnvrt[i], (self.gui_snk, i+1))
-
- self.gui_snk.set_update_time(0);
- self.gui_snk.set_fft_average(self._avg)
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
- self._nsamps = newnsamps
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- s.set_data(data)
-
- self.start()
+ self.setup()
def main():
description = "Plots the PSDs of a list of files. Files are a binary list of shorts."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-L", "--psd-size", type="int", default=2048,
- help="Set the FFT size of the PSD [default=%default]")
- parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0,
- help="Set the center frequency of the signal [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-a", "--average", type="float", default=1.0,
- help="Set amount of averaging (smaller=more averaging) [default=%default]")
- parser.add_option("-s", "--scale", type="eng_float", default=2**(16-1)-1,
- help="Set a scaling factor for the short->float conversion [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_short)
- max_nsamples = min(filesizes)
-
- tb = my_top_block(filelist,
- options.center_frequency, options.sample_rate,
- options.psd_size,
- options.start, nsamples, max_nsamples,
- options.scale, options.average)
+ tb = psd_plot_s(filelist,
+ options.center_frequency, options.sample_rate,
+ options.psd_size,
+ options.start, options.nsamples, max_nsamples,
+ options.average)
- main_box = dialog_box(tb, 'GNU Radio PSD Plot')
+ main_box = plot_base.plot_psd_form(tb, 'GNU Radio PSD Plot')
main_box.show()
tb.run()
@@ -181,4 +75,3 @@ if __name__ == "__main__":
main()
except KeyboardInterrupt:
pass
-
diff --git a/gr-qtgui/apps/gr_spectrogram_plot_b b/gr-qtgui/apps/gr_spectrogram_plot_b
index 649c2834d6..08ddd9efc3 100755
--- a/gr-qtgui/apps/gr_spectrogram_plot_b
+++ b/gr-qtgui/apps/gr_spectrogram_plot_b
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,10 +21,12 @@
#
from gnuradio import gr
-from gnuradio import blocks
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_spectrogram_base as plot_base
+except ImportError:
+ import plot_spectrogram_base as plot_base
try:
from gnuradio import qtgui
@@ -34,141 +36,35 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples_and_pad(filename, start, in_size, min_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_char, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.uint8, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- # If we have to, append 0's to create min_size samples of data
- if(len(data) < min_size):
- data += (min_size - len(data)) * [scipy.uint8(0)]
-
- return data
-
-class my_top_block(gr.top_block):
+class spectrogram_plot_b(plot_base.plot_base):
def __init__(self, filelist, fc, samp_rate, psdsize, start,
- nsamples, max_nsamples, scale, avg=1.0):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._center_freq = fc
- self._samp_rate = samp_rate
- self._psd_size = psdsize
- self._start = start
- self._max_nsamps = max_nsamples
- self._scale = scale
- self._nsigs = len(self._filelist)
- self._avg = avg
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_float, self._start)
- self.add = blocks.add_ff()
+ nsamples, max_nsamples, avg=1.0):
+ plot_base.plot_base.__init__(self, filelist, fc, samp_rate,
+ psdsize, start, nsamples,
+ max_nsamples, avg)
+
+ self.read_samples = plot_base.read_samples_b
+ self.dsize = gr.sizeof_float
+ self.src_type = plot_base.source_chars_to_float
self.gui_snk = qtgui.waterfall_sink_f(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS,
self._center_freq, self._samp_rate,
- "GNU Radio Spectrogram Plot")
- n = 0
- self.srcs = list()
- self.cnvrt = list()
- for f in filelist:
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- self.srcs.append(gr.vector_source_b(data))
- self.cnvrt.append(blocks.char_to_float(1, self._scale))
- n += 1
-
- self.connect(self.add, self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs):
- self.connect(s, self.cnvrt[i], (self.add, i))
-
- self.gui_snk.set_update_time(0);
- self.gui_snk.set_fft_average(self._avg)
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
- self._nsamps = newnsamps
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- s.set_data(data)
-
- self.start()
+ "GNU Radio Spectrogram Plot", self._nsigs)
+ self.setup()
def main():
- description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of chars/bytes."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-L", "--psd-size", type="int", default=2048,
- help="Set the FFT size of the PSD [default=%default]")
- parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0,
- help="Set the center frequency of the signal [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-a", "--average", type="float", default=1.0,
- help="Set amount of averaging (smaller=more averaging) [default=%default]")
- parser.add_option("-s", "--scale", type="eng_float", default=2**(8-1)-1,
- help="Set a scaling factor for the char->float conversion [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of chars."
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_char)
- max_nsamples = min(filesizes)
-
- tb = my_top_block(filelist,
- options.center_frequency, options.sample_rate,
- options.psd_size,
- options.start, nsamples, max_nsamples,
- options.scale, options.average);
+ tb = spectrogram_plot_b(filelist,
+ options.center_frequency, options.sample_rate,
+ options.psd_size,
+ options.start, options.nsamples, max_nsamples,
+ options.average);
- main_box = dialog_box(tb, 'GNU Radio Spectrogram Plot')
+ main_box = plot_base.plot_spectrogram_form(tb, 'GNU Radio Time Plot')
main_box.show()
tb.run()
diff --git a/gr-qtgui/apps/gr_spectrogram_plot_c b/gr-qtgui/apps/gr_spectrogram_plot_c
index 160072f27c..230170c1ee 100755
--- a/gr-qtgui/apps/gr_spectrogram_plot_c
+++ b/gr-qtgui/apps/gr_spectrogram_plot_c
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,10 +21,12 @@
#
from gnuradio import gr
-from gnuradio import blocks
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_spectrogram_base as plot_base
+except ImportError:
+ import plot_spectrogram_base as plot_base
try:
from gnuradio import qtgui
@@ -34,136 +36,35 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples_and_pad(filename, start, in_size, min_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_gr_complex, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.complex64, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- # If we have to, append 0's to create min_size samples of data
- if(len(data) < min_size):
- data += (min_size - len(data)) * [complex(0,0)]
-
- return data
-
-class my_top_block(gr.top_block):
+class spectrogram_plot_c(plot_base.plot_base):
def __init__(self, filelist, fc, samp_rate, psdsize, start,
nsamples, max_nsamples, avg=1.0):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._center_freq = fc
- self._samp_rate = samp_rate
- self._psd_size = psdsize
- self._start = start
- self._max_nsamps = max_nsamples
- self._nsigs = len(self._filelist)
- self._avg = avg
+ plot_base.plot_base.__init__(self, filelist, fc, samp_rate,
+ psdsize, start, nsamples,
+ max_nsamples, avg)
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_gr_complex, self._start)
- self.add = blocks.add_cc()
+ self.read_samples = plot_base.read_samples_c
+ self.dsize = gr.sizeof_gr_complex
+ self.src_type = gr.vector_source_c
self.gui_snk = qtgui.waterfall_sink_c(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS,
self._center_freq, self._samp_rate,
- "GNU Radio Spectrogram Plot")
- n = 0
- self.srcs = list()
- for f in filelist:
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- self.srcs.append(gr.vector_source_c(data))
- n += 1
-
- self.connect(self.add, self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs):
- self.connect(s, (self.add, i))
-
- self.gui_snk.set_update_time(0);
- self.gui_snk.set_fft_average(self._avg)
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
- self._nsamps = newnsamps
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- s.set_data(data)
-
- self.start()
+ "GNU Radio Spectrogram Plot", self._nsigs)
+ self.setup()
def main():
description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of complex floats."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-L", "--psd-size", type="int", default=2048,
- help="Set the FFT size of the PSD [default=%default]")
- parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0,
- help="Set the center frequency of the signal [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-a", "--average", type="float", default=1.0,
- help="Set amount of averaging (smaller=more averaging) [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_gr_complex)
- max_nsamples = min(filesizes)
-
- tb = my_top_block(filelist,
- options.center_frequency, options.sample_rate,
- options.psd_size,
- options.start, nsamples, max_nsamples,
- options.average);
+ tb = spectrogram_plot_c(filelist,
+ options.center_frequency, options.sample_rate,
+ options.psd_size,
+ options.start, options.nsamples, max_nsamples,
+ options.average);
- main_box = dialog_box(tb, 'GNU Radio Spectrogram Plot')
+ main_box = plot_base.plot_spectrogram_form(tb, 'GNU Radio Spectrogram Plot')
main_box.show()
tb.run()
diff --git a/gr-qtgui/apps/gr_spectrogram_plot_f b/gr-qtgui/apps/gr_spectrogram_plot_f
index 3e799395b3..a26f3257f1 100755
--- a/gr-qtgui/apps/gr_spectrogram_plot_f
+++ b/gr-qtgui/apps/gr_spectrogram_plot_f
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,10 +21,12 @@
#
from gnuradio import gr
-from gnuradio import blocks
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_spectrogram_base as plot_base
+except ImportError:
+ import plot_spectrogram_base as plot_base
try:
from gnuradio import qtgui
@@ -34,136 +36,35 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples_and_pad(filename, start, in_size, min_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_float, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.float32, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- # If we have to, append 0's to create min_size samples of data
- if(len(data) < min_size):
- data += (min_size - len(data)) * [scipy.float32(0.0)]
-
- return data
-
-class my_top_block(gr.top_block):
+class spectrogram_plot_f(plot_base.plot_base):
def __init__(self, filelist, fc, samp_rate, psdsize, start,
nsamples, max_nsamples, avg=1.0):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._center_freq = fc
- self._samp_rate = samp_rate
- self._psd_size = psdsize
- self._start = start
- self._max_nsamps = max_nsamples
- self._nsigs = len(self._filelist)
- self._avg = avg
+ plot_base.plot_base.__init__(self, filelist, fc, samp_rate,
+ psdsize, start, nsamples,
+ max_nsamples, avg)
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_float, self._start)
- self.add = blocks.add_ff()
+ self.read_samples = plot_base.read_samples_f
+ self.dsize = gr.sizeof_float
+ self.src_type = gr.vector_source_f
self.gui_snk = qtgui.waterfall_sink_f(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS,
self._center_freq, self._samp_rate,
- "GNU Radio Spectrogram Plot")
- n = 0
- self.srcs = list()
- for f in filelist:
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- self.srcs.append(gr.vector_source_f(data))
- n += 1
-
- self.connect(self.add, self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs):
- self.connect(s, (self.add, i))
-
- self.gui_snk.set_update_time(0);
- self.gui_snk.set_fft_average(self._avg)
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
- self._nsamps = newnsamps
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- s.set_data(data)
-
- self.start()
+ "GNU Radio Spectrogram Plot", self._nsigs)
+ self.setup()
def main():
description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of floats."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-L", "--psd-size", type="int", default=2048,
- help="Set the FFT size of the PSD [default=%default]")
- parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0,
- help="Set the center frequency of the signal [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-a", "--average", type="float", default=1.0,
- help="Set amount of averaging (smaller=more averaging) [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_float)
- max_nsamples = min(filesizes)
-
- tb = my_top_block(filelist,
- options.center_frequency, options.sample_rate,
- options.psd_size,
- options.start, nsamples, max_nsamples,
- options.average);
+ tb = spectrogram_plot_f(filelist,
+ options.center_frequency, options.sample_rate,
+ options.psd_size,
+ options.start, options.nsamples, max_nsamples,
+ options.average);
- main_box = dialog_box(tb, 'GNU Radio Spectrogram Plot')
+ main_box = plot_base.plot_spectrogram_form(tb, 'GNU Radio Time Plot')
main_box.show()
tb.run()
diff --git a/gr-qtgui/apps/gr_spectrogram_plot_i b/gr-qtgui/apps/gr_spectrogram_plot_i
index 444f4115ad..823aedfcbc 100755
--- a/gr-qtgui/apps/gr_spectrogram_plot_i
+++ b/gr-qtgui/apps/gr_spectrogram_plot_i
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,10 +21,12 @@
#
from gnuradio import gr
-from gnuradio import blocks
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_spectrogram_base as plot_base
+except ImportError:
+ import plot_spectrogram_base as plot_base
try:
from gnuradio import qtgui
@@ -34,141 +36,35 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples_and_pad(filename, start, in_size, min_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_int, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.int32, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- # If we have to, append 0's to create min_size samples of data
- if(len(data) < min_size):
- data += (min_size - len(data)) * [scipy.int32(0)]
-
- return data
-
-class my_top_block(gr.top_block):
+class spectrogram_plot_i(plot_base.plot_base):
def __init__(self, filelist, fc, samp_rate, psdsize, start,
- nsamples, max_nsamples, scale, avg=1.0):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._center_freq = fc
- self._samp_rate = samp_rate
- self._psd_size = psdsize
- self._start = start
- self._max_nsamps = max_nsamples
- self._scale = scale
- self._nsigs = len(self._filelist)
- self._avg = avg
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_float, self._start)
- self.add = blocks.add_ff()
+ nsamples, max_nsamples, avg=1.0):
+ plot_base.plot_base.__init__(self, filelist, fc, samp_rate,
+ psdsize, start, nsamples,
+ max_nsamples, avg)
+
+ self.read_samples = plot_base.read_samples_i
+ self.dsize = gr.sizeof_float
+ self.src_type = plot_base.source_ints_to_float
self.gui_snk = qtgui.waterfall_sink_f(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS,
self._center_freq, self._samp_rate,
- "GNU Radio Spectrogram Plot")
- n = 0
- self.srcs = list()
- self.cnvrt = list()
- for f in filelist:
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- self.srcs.append(gr.vector_source_i(data))
- self.cnvrt.append(blocks.int_to_float(1, self._scale))
- n += 1
-
- self.connect(self.add, self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs):
- self.connect(s, self.cnvrt[i], (self.add, i))
-
- self.gui_snk.set_update_time(0);
- self.gui_snk.set_fft_average(self._avg)
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
- self._nsamps = newnsamps
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- s.set_data(data)
-
- self.start()
+ "GNU Radio Spectrogram Plot", self._nsigs)
+ self.setup()
def main():
- description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of integers."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-L", "--psd-size", type="int", default=2048,
- help="Set the FFT size of the PSD [default=%default]")
- parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0,
- help="Set the center frequency of the signal [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-a", "--average", type="float", default=1.0,
- help="Set amount of averaging (smaller=more averaging) [default=%default]")
- parser.add_option("-s", "--scale", type="eng_float", default=2**(32-1)-1,
- help="Set a scaling factor for the int->float conversion [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of ints."
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_int)
- max_nsamples = min(filesizes)
-
- tb = my_top_block(filelist,
- options.center_frequency, options.sample_rate,
- options.psd_size,
- options.start, nsamples, max_nsamples,
- options.scale, options.average);
+ tb = spectrogram_plot_i(filelist,
+ options.center_frequency, options.sample_rate,
+ options.psd_size,
+ options.start, options.nsamples, max_nsamples,
+ options.average);
- main_box = dialog_box(tb, 'GNU Radio Spectrogram Plot')
+ main_box = plot_base.plot_spectrogram_form(tb, 'GNU Radio Time Plot')
main_box.show()
tb.run()
diff --git a/gr-qtgui/apps/gr_spectrogram_plot_s b/gr-qtgui/apps/gr_spectrogram_plot_s
index bb3573ba2c..501d1c425c 100755
--- a/gr-qtgui/apps/gr_spectrogram_plot_s
+++ b/gr-qtgui/apps/gr_spectrogram_plot_s
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,10 +21,12 @@
#
from gnuradio import gr
-from gnuradio import blocks
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_spectrogram_base as plot_base
+except ImportError:
+ import plot_spectrogram_base as plot_base
try:
from gnuradio import qtgui
@@ -34,141 +36,35 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples_and_pad(filename, start, in_size, min_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_short, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.int16, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- # If we have to, append 0's to create min_size samples of data
- if(len(data) < min_size):
- data += (min_size - len(data)) * [scipy.int16(0)]
-
- return data
-
-class my_top_block(gr.top_block):
+class spectrogram_plot_s(plot_base.plot_base):
def __init__(self, filelist, fc, samp_rate, psdsize, start,
- nsamples, max_nsamples, scale, avg=1.0):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._center_freq = fc
- self._samp_rate = samp_rate
- self._psd_size = psdsize
- self._start = start
- self._max_nsamps = max_nsamples
- self._scale = scale
- self._nsigs = len(self._filelist)
- self._avg = avg
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_float, self._start)
- self.add = blocks.add_ff()
+ nsamples, max_nsamples, avg=1.0):
+ plot_base.plot_base.__init__(self, filelist, fc, samp_rate,
+ psdsize, start, nsamples,
+ max_nsamples, avg)
+
+ self.read_samples = plot_base.read_samples_s
+ self.dsize = gr.sizeof_float
+ self.src_type = plot_base.source_shorts_to_float
self.gui_snk = qtgui.waterfall_sink_f(self._psd_size, gr.firdes.WIN_BLACKMAN_hARRIS,
self._center_freq, self._samp_rate,
- "GNU Radio Spectrogram Plot")
- n = 0
- self.srcs = list()
- self.cnvrt = list()
- for f in filelist:
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- self.srcs.append(gr.vector_source_s(data))
- self.cnvrt.append(blocks.short_to_float(1, self._scale))
- n += 1
-
- self.connect(self.add, self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs):
- self.connect(s, self.cnvrt[i], (self.add, i))
-
- self.gui_snk.set_update_time(0);
- self.gui_snk.set_fft_average(self._avg)
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
- self._nsamps = newnsamps
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples_and_pad(f, self._start,
- self._nsamps, self._psd_size)
- s.set_data(data)
-
- self.start()
+ "GNU Radio Spectrogram Plot", self._nsigs)
+ self.setup()
def main():
description = "Plots the spectrogram (waterfall) of a list of files. Files are a binary list of shorts."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-L", "--psd-size", type="int", default=2048,
- help="Set the FFT size of the PSD [default=%default]")
- parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0,
- help="Set the center frequency of the signal [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-a", "--average", type="float", default=1.0,
- help="Set amount of averaging (smaller=more averaging) [default=%default]")
- parser.add_option("-s", "--scale", type="eng_float", default=2**(16-1)-1,
- help="Set a scaling factor for the short->float conversion [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_short)
- max_nsamples = min(filesizes)
-
- tb = my_top_block(filelist,
- options.center_frequency, options.sample_rate,
- options.psd_size,
- options.start, nsamples, max_nsamples,
- options.scale, options.average);
+ tb = spectrogram_plot_s(filelist,
+ options.center_frequency, options.sample_rate,
+ options.psd_size,
+ options.start, options.nsamples, max_nsamples,
+ options.average);
- main_box = dialog_box(tb, 'GNU Radio Spectrogram Plot')
+ main_box = plot_base.plot_spectrogram_form(tb, 'GNU Radio Time Plot')
main_box.show()
tb.run()
diff --git a/gr-qtgui/apps/gr_time_plot_b b/gr-qtgui/apps/gr_time_plot_b
index 4b63c3fd11..0d5ce5e501 100755
--- a/gr-qtgui/apps/gr_time_plot_b
+++ b/gr-qtgui/apps/gr_time_plot_b
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,10 +21,12 @@
#
from gnuradio import gr
-from gnuradio import blocks
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_tiome_base as plot_base
+except ImportError:
+ import plot_time_base as plot_base
try:
from gnuradio import qtgui
@@ -34,132 +36,32 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples(filename, start, in_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_char, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.uint8, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- if(len(data) < in_size):
- print "Warning: read in {0} samples but asked for {1} samples.".format(
- len(data), in_size)
-
- return data
-
-class gr_time_plot_f(gr.top_block):
- def __init__(self, filelist, samp_rate, start, nsamples, max_nsamples, scale):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._samp_rate = samp_rate
- self._start = start
- self._max_nsamps = max_nsamples
- self._scale = scale
- self._nsigs = len(self._filelist)
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_float, self._start)
+class plot_time_b(plot_base.plot_base):
+ def __init__(self, filelist, samp_rate,
+ start, nsamples, max_nsamples,
+ auto_scale):
+ plot_base.plot_base.__init__(self, filelist, samp_rate,
+ start, nsamples, max_nsamples,
+ auto_scale)
+ self.read_samples = plot_base.read_samples_b
+ self.dsize = gr.sizeof_float # already converted
+ self.src_type = plot_base.source_chars_to_float
self.gui_snk = qtgui.time_sink_f(self._nsamps, self._samp_rate,
"GNU Radio Time Plot", self._nsigs)
- n = 0
- self.srcs = list()
- self.cnvrt = list()
- for f in filelist:
- data = read_samples(f, self._start, self._nsamps)
- self.srcs.append(gr.vector_source_b(data))
- self.cnvrt.append(blocks.char_to_float(1, self._scale))
-
- # Set default labels based on file names
- fname = f.split("/")[-1]
- self.gui_snk.set_line_label(n, "{0}".format(fname))
- n += 1
-
- self.connect(self.srcs[0], self.cnvrt[0], self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs[1:]):
- self.connect(s, self.cnvrt[i], (self.gui_snk, i+1))
-
- self.gui_snk.set_update_time(0);
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples(f, self._start, newnsamps)
- s.set_data(data)
- if(len(data) < newnsamps):
- newnsamps = len(data)
-
- self._nsamps = newnsamps
- self.gui_snk.set_nsamps(self._nsamps)
-
- self.start()
+ self.setup()
def main():
- description = "Plots a list of files on a scope plot. Files are a binary list of chars/bytes."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-s", "--scale", type="eng_float", default=2**(8-1)-1,
- help="Set a scaling factor for the char->float conversion [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ description = "Plots a list of files on a scope plot. Files are a binary list of chars."
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_char)
- max_nsamples = min(filesizes)
-
- tb = gr_time_plot_f(filelist, options.sample_rate,
- options.start, nsamples, max_nsamples,
- options.scale);
+ tb = plot_time_b(filelist, options.sample_rate,
+ options.start, options.nsamples, max_nsamples,
+ not options.no_auto_scale)
- main_box = dialog_box(tb, 'GNU Radio Time Plot')
+ main_box = plot_base.plot_time_form(tb, 'GNU Radio Time Plot')
main_box.show()
tb.run()
@@ -170,4 +72,3 @@ if __name__ == "__main__":
main()
except KeyboardInterrupt:
pass
-
diff --git a/gr-qtgui/apps/gr_time_plot_c b/gr-qtgui/apps/gr_time_plot_c
index 2f27623e54..4450a2074c 100755
--- a/gr-qtgui/apps/gr_time_plot_c
+++ b/gr-qtgui/apps/gr_time_plot_c
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,9 +21,12 @@
#
from gnuradio import gr
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_time_base as plot_base
+except ImportError:
+ import plot_time_base as plot_base
try:
from gnuradio import qtgui
@@ -33,127 +36,33 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples(filename, start, in_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_gr_complex, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.complex64, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- if(len(data) < in_size):
- print "Warning: read in {0} samples but asked for {1} samples.".format(
- len(data), in_size)
-
- return data
-
-class my_top_block(gr.top_block):
- def __init__(self, filelist, samp_rate, start, nsamples, max_nsamples):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._samp_rate = samp_rate
- self._start = start
- self._max_nsamps = max_nsamples
- self._nsigs = len(self._filelist)
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_gr_complex, self._start)
+class plot_time_c(plot_base.plot_base):
+ def __init__(self, filelist, samp_rate,
+ start, nsamples, max_nsamples,
+ auto_scale):
+ plot_base.plot_base.__init__(self, filelist, samp_rate,
+ start, nsamples, max_nsamples,
+ auto_scale)
+ self.read_samples = plot_base.read_samples_c
+ self.dsize = gr.sizeof_gr_complex
+ self.src_type = gr.vector_source_c
self.gui_snk = qtgui.time_sink_c(self._nsamps, self._samp_rate,
"GNU Radio Time Plot", self._nsigs)
- n = 0
- self.srcs = list()
- for f in filelist:
- data = read_samples(f, self._start, self._nsamps)
- self.srcs.append(gr.vector_source_c(data))
-
- # Set default labels based on file names
- fname = f.split("/")[-1]
- self.gui_snk.set_line_label(n, "Re{{{0}}}".format(fname))
- self.gui_snk.set_line_label(n+1, "Im{{{0}}}".format(fname))
- n += 2
-
- self.connect(self.srcs[0], self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs[1:]):
- self.connect(s, (self.gui_snk, i+1))
-
- self.gui_snk.set_update_time(0);
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples(f, self._start, newnsamps)
- s.set_data(data)
- if(len(data) < newnsamps):
- newnsamps = len(data)
-
- self._nsamps = newnsamps
- self.gui_snk.set_nsamps(self._nsamps)
-
- self.start()
+ self._nsigs *= 2 # complex plots have real/imag
+ self.setup()
def main():
description = "Plots a list of files on a scope plot. Files are a binary list of complex floats."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_gr_complex)
- max_nsamples = min(filesizes)
-
- tb = my_top_block(filelist, options.sample_rate,
- options.start, nsamples, max_nsamples);
+ tb = plot_time_c(filelist, options.sample_rate,
+ options.start, options.nsamples, max_nsamples,
+ not options.no_auto_scale)
- main_box = dialog_box(tb, 'GNU Radio Time Plot')
+ main_box = plot_base.plot_time_form(tb, 'GNU Radio Time Plot')
main_box.show()
tb.run()
diff --git a/gr-qtgui/apps/gr_time_plot_f b/gr-qtgui/apps/gr_time_plot_f
index e4f4b8d436..4cac6e9323 100755
--- a/gr-qtgui/apps/gr_time_plot_f
+++ b/gr-qtgui/apps/gr_time_plot_f
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,9 +21,12 @@
#
from gnuradio import gr
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_time_base as plot_base
+except ImportError:
+ import plot_time_base as plot_base
try:
from gnuradio import qtgui
@@ -33,126 +36,32 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples(filename, start, in_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_float, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.float32, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- if(len(data) < in_size):
- print "Warning: read in {0} samples but asked for {1} samples.".format(
- len(data), in_size)
-
- return data
-
-class gr_time_plot_f(gr.top_block):
- def __init__(self, filelist, samp_rate, start, nsamples, max_nsamples):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._samp_rate = samp_rate
- self._start = start
- self._max_nsamps = max_nsamples
- self._nsigs = len(self._filelist)
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_float, self._start)
+class plot_time_f(plot_base.plot_base):
+ def __init__(self, filelist, samp_rate,
+ start, nsamples, max_nsamples,
+ auto_scale):
+ plot_base.plot_base.__init__(self, filelist, samp_rate,
+ start, nsamples, max_nsamples,
+ auto_scale)
+ self.read_samples = plot_base.read_samples_f
+ self.dsize = gr.sizeof_float
+ self.src_type = gr.vector_source_f
self.gui_snk = qtgui.time_sink_f(self._nsamps, self._samp_rate,
"GNU Radio Time Plot", self._nsigs)
- n = 0
- self.srcs = list()
- for f in filelist:
- data = read_samples(f, self._start, self._nsamps)
- self.srcs.append(gr.vector_source_f(data))
-
- # Set default labels based on file names
- fname = f.split("/")[-1]
- self.gui_snk.set_line_label(n, "{0}".format(fname))
- n += 1
-
- self.connect(self.srcs[0], self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs[1:]):
- self.connect(s, (self.gui_snk, i+1))
-
- self.gui_snk.set_update_time(0);
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples(f, self._start, newnsamps)
- s.set_data(data)
- if(len(data) < newnsamps):
- newnsamps = len(data)
-
- self._nsamps = newnsamps
- self.gui_snk.set_nsamps(self._nsamps)
-
- self.start()
+ self.setup()
def main():
description = "Plots a list of files on a scope plot. Files are a binary list of floats."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_float)
- max_nsamples = min(filesizes)
-
- tb = gr_time_plot_f(filelist, options.sample_rate,
- options.start, nsamples, max_nsamples);
+ tb = plot_time_f(filelist, options.sample_rate,
+ options.start, options.nsamples, max_nsamples,
+ not options.no_auto_scale)
- main_box = dialog_box(tb, 'GNU Radio Time Plot')
+ main_box = plot_base.plot_time_form(tb, 'GNU Radio Time Plot')
main_box.show()
tb.run()
@@ -163,4 +72,3 @@ if __name__ == "__main__":
main()
except KeyboardInterrupt:
pass
-
diff --git a/gr-qtgui/apps/gr_time_plot_i b/gr-qtgui/apps/gr_time_plot_i
index 4895090a10..04229de0cd 100755
--- a/gr-qtgui/apps/gr_time_plot_i
+++ b/gr-qtgui/apps/gr_time_plot_i
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,10 +21,12 @@
#
from gnuradio import gr
-from gnuradio import blocks
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_time_base as plot_base
+except ImportError:
+ import plot_time_base as plot_base
try:
from gnuradio import qtgui
@@ -34,132 +36,32 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples(filename, start, in_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_int, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.int32, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- if(len(data) < in_size):
- print "Warning: read in {0} samples but asked for {1} samples.".format(
- len(data), in_size)
-
- return data
-
-class gr_time_plot_f(gr.top_block):
- def __init__(self, filelist, samp_rate, start, nsamples, max_nsamples, scale):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._samp_rate = samp_rate
- self._start = start
- self._max_nsamps = max_nsamples
- self._scale = scale
- self._nsigs = len(self._filelist)
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_float, self._start)
+class plot_time_i(plot_base.plot_base):
+ def __init__(self, filelist, samp_rate,
+ start, nsamples, max_nsamples,
+ auto_scale):
+ plot_base.plot_base.__init__(self, filelist, samp_rate,
+ start, nsamples, max_nsamples,
+ auto_scale)
+ self.read_samples = plot_base.read_samples_i
+ self.dsize = gr.sizeof_float # already converted
+ self.src_type = plot_base.source_ints_to_float
self.gui_snk = qtgui.time_sink_f(self._nsamps, self._samp_rate,
"GNU Radio Time Plot", self._nsigs)
- n = 0
- self.srcs = list()
- self.cnvrt = list()
- for f in filelist:
- data = read_samples(f, self._start, self._nsamps)
- self.srcs.append(gr.vector_source_i(data))
- self.cnvrt.append(blocks.int_to_float(1, self._scale))
-
- # Set default labels based on file names
- fname = f.split("/")[-1]
- self.gui_snk.set_line_label(n, "{0}".format(fname))
- n += 1
-
- self.connect(self.srcs[0], self.cnvrt[0], self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs[1:]):
- self.connect(s, self.cnvrt[i], (self.gui_snk, i+1))
-
- self.gui_snk.set_update_time(0);
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples(f, self._start, newnsamps)
- s.set_data(data)
- if(len(data) < newnsamps):
- newnsamps = len(data)
-
- self._nsamps = newnsamps
- self.gui_snk.set_nsamps(self._nsamps)
-
- self.start()
+ self.setup()
def main():
description = "Plots a list of files on a scope plot. Files are a binary list of integers."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-s", "--scale", type="eng_float", default=2**(32-1)-1,
- help="Set a scaling factor for the int->float conversion [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_int)
- max_nsamples = min(filesizes)
+ tb = plot_time_i(filelist, options.sample_rate,
+ options.start, options.nsamples, max_nsamples,
+ not options.no_auto_scale)
- tb = gr_time_plot_f(filelist, options.sample_rate,
- options.start, nsamples, max_nsamples,
- options.scale);
-
- main_box = dialog_box(tb, 'GNU Radio Time Plot')
+ main_box = plot_base.plot_time_form(tb, 'GNU Radio Time Plot')
main_box.show()
tb.run()
@@ -170,4 +72,3 @@ if __name__ == "__main__":
main()
except KeyboardInterrupt:
pass
-
diff --git a/gr-qtgui/apps/gr_time_plot_s b/gr-qtgui/apps/gr_time_plot_s
index 581190e6df..cc4a8a7812 100755
--- a/gr-qtgui/apps/gr_time_plot_s
+++ b/gr-qtgui/apps/gr_time_plot_s
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,9 +21,12 @@
#
from gnuradio import gr
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import os, sys
+import scipy
+
+try:
+ import gnuradio.qtgui.plot_time_base as plot_base
+except ImportError:
+ import plot_time_base as plot_base
try:
from gnuradio import qtgui
@@ -33,132 +36,32 @@ except ImportError:
print "Error: Program requires PyQt4 and gr-qtgui."
sys.exit(1)
-try:
- import scipy
-except ImportError:
- print "Error: Scipy required (www.scipy.org)."
- sys.exit(1)
-
-try:
- from gnuradio.qtgui.plot_form import *
-except ImportError:
- from plot_form import *
-
-def read_samples(filename, start, in_size):
- # Read in_size number of samples from file
- fhandle = open(filename, 'r')
- fhandle.seek(start*gr.sizeof_short, 0)
- data = scipy.fromfile(fhandle, dtype=scipy.int16, count=in_size)
- data = data.tolist()
- fhandle.close()
-
- if(len(data) < in_size):
- print "Warning: read in {0} samples but asked for {1} samples.".format(
- len(data), in_size)
-
- return data
-
-class gr_time_plot_f(gr.top_block):
- def __init__(self, filelist, samp_rate, start, nsamples, max_nsamples, scale):
- gr.top_block.__init__(self)
-
- self._filelist = filelist
- self._samp_rate = samp_rate
- self._start = start
- self._max_nsamps = max_nsamples
- self._scale = scale
- self._nsigs = len(self._filelist)
-
- if(nsamples is None):
- self._nsamps = max_nsamples
- else:
- self._nsamps = nsamples
-
- self.qapp = QtGui.QApplication(sys.argv)
-
- self.skip = gr.skiphead(gr.sizeof_float, self._start)
+class plot_time_s(plot_base.plot_base):
+ def __init__(self, filelist, samp_rate,
+ start, nsamples, max_nsamples,
+ auto_scale):
+ plot_base.plot_base.__init__(self, filelist, samp_rate,
+ start, nsamples, max_nsamples,
+ auto_scale)
+ self.read_samples = plot_base.read_samples_s
+ self.dsize = gr.sizeof_float # already converted
+ self.src_type = plot_base.source_shorts_to_float
self.gui_snk = qtgui.time_sink_f(self._nsamps, self._samp_rate,
"GNU Radio Time Plot", self._nsigs)
- n = 0
- self.srcs = list()
- self.cnvrt = list()
- for f in filelist:
- data = read_samples(f, self._start, self._nsamps)
- self.srcs.append(gr.vector_source_s(data))
- self.cnvrt.append(blocks.short_to_float(1, self._scale))
-
- # Set default labels based on file names
- fname = f.split("/")[-1]
- self.gui_snk.set_line_label(n, "{0}".format(fname))
- n += 1
-
- self.connect(self.srcs[0], self.cnvrt[0], self.skip)
- self.connect(self.skip, (self.gui_snk, 0))
-
- for i,s in enumerate(self.srcs[1:]):
- self.connect(s, self.cnvrt[i], (self.gui_snk, i+1))
-
- self.gui_snk.set_update_time(0);
-
- # Get Python Qt references
- pyQt = self.gui_snk.pyqwidget()
- self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
-
- def get_gui(self):
- return self.pyWin
-
- def reset(self, newstart, newnsamps):
- self.stop()
- self.wait()
-
- self._start = newstart
-
- for s,f in zip(self.srcs, self._filelist):
- data = read_samples(f, self._start, newnsamps)
- s.set_data(data)
- if(len(data) < newnsamps):
- newnsamps = len(data)
-
- self._nsamps = newnsamps
- self.gui_snk.set_nsamps(self._nsamps)
-
- self.start()
+ self.setup()
def main():
description = "Plots a list of files on a scope plot. Files are a binary list of shorts."
- parser = OptionParser(option_class=eng_option, description=description,
- conflict_handler="resolve")
- parser.add_option("-N", "--nsamples", type="int", default=None,
- help="Set the number of samples to display [default=prints entire file]")
- parser.add_option("-S", "--start", type="int", default=0,
- help="Starting sample number [default=%default]")
- parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
- help="Set the sample rate of the signal [default=%default]")
- parser.add_option("-s", "--scale", type="eng_float", default=2**(16-1)-1,
- help="Set a scaling factor for the short->float conversion [default=%default]")
- (options, args) = parser.parse_args()
-
- if(len(args) < 1):
- parser.print_help()
- sys.exit(0)
+ (options, args) = plot_base.setup_options(description)
filelist = list(args)
+ max_nsamples = plot_base.find_max_nsamples(filelist)
- nsamples = options.nsamples
-
- # Find the smallest number of samples in all files and use that as
- # a maximum value possible.
- filesizes = []
- for f in filelist:
- if(os.path.exists(f)):
- filesizes.append(os.path.getsize(f) / gr.sizeof_short)
- max_nsamples = min(filesizes)
-
- tb = gr_time_plot_f(filelist, options.sample_rate,
- options.start, nsamples, max_nsamples,
- options.scale);
+ tb = plot_time_s(filelist, options.sample_rate,
+ options.start, options.nsamples, max_nsamples,
+ not options.no_auto_scale)
- main_box = dialog_box(tb, 'GNU Radio Time Plot')
+ main_box = plot_base.plot_time_form(tb, 'GNU Radio Time Plot')
main_box.show()
tb.run()
@@ -169,4 +72,3 @@ if __name__ == "__main__":
main()
except KeyboardInterrupt:
pass
-
diff --git a/gr-qtgui/apps/plot_base.py b/gr-qtgui/apps/plot_base.py
new file mode 100644
index 0000000000..5a784b2dfd
--- /dev/null
+++ b/gr-qtgui/apps/plot_base.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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, blocks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import os, sys
+
+try:
+ from gnuradio import qtgui
+ from PyQt4 import QtGui, QtCore
+ import sip
+except ImportError:
+ print "Error: Program requires PyQt4 and gr-qtgui."
+ sys.exit(1)
+
+try:
+ import scipy
+except ImportError:
+ print "Error: Scipy required (www.scipy.org)."
+ sys.exit(1)
+
+try:
+ from gnuradio.qtgui.plot_constellation_form import *
+ from gnuradio.qtgui.plot_psd_form import *
+ from gnuradio.qtgui.plot_spectrogram_form import *
+ from gnuradio.qtgui.plot_time_form import *
+except ImportError:
+ from plot_constellation_form import *
+ from plot_psd_form import *
+ from plot_spectrogram_form import *
+ from plot_time_form import *
+
+def read_samples(filename, start, in_size, min_size, dtype, dtype_size):
+ # Read in_size number of samples from file
+ fhandle = open(filename, 'r')
+ fhandle.seek(start*dtype_size, 0)
+ data = scipy.fromfile(fhandle, dtype=dtype, count=in_size)
+ data_min = 1.1*data.min()
+ data_max = 1.1*data.max()
+ data = data.tolist()
+ fhandle.close()
+
+ if(min_size > 0):
+ if(len(data) < in_size):
+ print "Warning: read in {0} samples but asked for {1} samples.".format(
+ len(data), in_size)
+ else:
+ # If we have to, append 0's to create min_size samples of data
+ if(len(data) < min_size):
+ data += (min_size - len(data)) * [dtype(0)]
+
+
+ return data, data_min, data_max
+
+def read_samples_f(filename, start, in_size, min_size=0):
+ return read_samples(filename, start, in_size, min_size,
+ scipy.float32, gr.sizeof_float)
+
+def read_samples_i(filename, start, in_size, min_size=0):
+ return read_samples(filename, start, in_size, min_size,
+ scipy.int32, gr.sizeof_int)
+
+def read_samples_s(filename, start, in_size, min_size=0):
+ return read_samples(filename, start, in_size, min_size,
+ scipy.int16, gr.sizeof_short)
+
+def read_samples_b(filename, start, in_size, min_size=0):
+ return read_samples(filename, start, in_size, min_size,
+ scipy.uint8, gr.sizeof_char)
+
+def read_samples_c(filename, start, in_size, min_size=0):
+ # Complex samples are handled differently
+ fhandle = open(filename, 'r')
+ fhandle.seek(start*gr.sizeof_gr_complex, 0)
+ data = scipy.fromfile(fhandle, dtype=scipy.complex64, count=in_size)
+ data_min = 1.1*float(min(data.real.min(), data.imag.min()))
+ data_max = 1.1*float(max(data.real.max(), data.imag.max()))
+ data = data.tolist()
+ fhandle.close()
+
+ if(min_size > 0):
+ if(len(data) < in_size):
+ print "Warning: read in {0} samples but asked for {1} samples.".format(
+ len(data), in_size)
+ else:
+ # If we have to, append 0's to create min_size samples of data
+ if(len(data) < min_size):
+ data += (min_size - len(data)) * [complex(0,0)]
+
+ return data, data_min, data_max
+
+class source_ints_to_float(gr.hier_block2):
+ def __init__(self, data):
+ gr.hier_block2.__init__(self, "ints_to_floats",
+ gr.io_signature(0, 0, 0),
+ gr.io_signature(1, 1, gr.sizeof_float))
+ self.src = gr.vector_source_i(data)
+ self.cvt = blocks.int_to_float()
+ self.connect(self.src, self.cvt, self)
+
+ def set_data(self, data):
+ self.src.set_data(data)
+
+class source_shorts_to_float(gr.hier_block2):
+ def __init__(self, data):
+ gr.hier_block2.__init__(self, "shorts_to_floats",
+ gr.io_signature(0, 0, 0),
+ gr.io_signature(1, 1, gr.sizeof_float))
+ self.src = gr.vector_source_s(data)
+ self.cvt = blocks.short_to_float()
+ self.connect(self.src, self.cvt, self)
+
+ def set_data(self, data):
+ self.src.set_data(data)
+
+class source_chars_to_float(gr.hier_block2):
+ def __init__(self, data):
+ gr.hier_block2.__init__(self, "chars_to_floats",
+ gr.io_signature(0, 0, 0),
+ gr.io_signature(1, 1, gr.sizeof_float))
+ self.src = gr.vector_source_b(data)
+ self.cvt = blocks.char_to_float()
+ self.connect(self.src, self.cvt, self)
+
+ def set_data(self, data):
+ self.src.set_data(data)
+
+def find_max_nsamples(filelist):
+ # Find the smallest number of samples in all files and use that as
+ # a maximum value possible.
+ filesizes = []
+ for f in filelist:
+ if(os.path.exists(f)):
+ filesizes.append(os.path.getsize(f) / gr.sizeof_gr_complex)
+ max_nsamples = min(filesizes)
+ return max_nsamples
diff --git a/gr-qtgui/apps/plot_constellation_form.py b/gr-qtgui/apps/plot_constellation_form.py
new file mode 100644
index 0000000000..6f67000ea2
--- /dev/null
+++ b/gr-qtgui/apps/plot_constellation_form.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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.
+#
+
+import sys
+from gnuradio import filter
+
+try:
+ from PyQt4 import QtGui, QtCore
+ import sip
+except ImportError:
+ print "Error: Program requires PyQt4."
+ sys.exit(1)
+
+try:
+ from gnuradio.qtgui.plot_from import plot_form
+except ImportError:
+ from plot_form import plot_form
+
+class plot_constellation_form(plot_form):
+ def __init__(self, top_block, title=''):
+ plot_form.__init__(self, top_block, title)
+
+ self.right_col_layout = QtGui.QVBoxLayout()
+ self.right_col_form = QtGui.QFormLayout()
+ self.right_col_layout.addLayout(self.right_col_form)
+ self.layout.addLayout(self.right_col_layout, 1,4,1,1)
+
+ self.auto_scale = QtGui.QCheckBox("Auto Scale", self)
+ if(self.top_block._auto_scale):
+ self.auto_scale.setChecked(self.top_block._auto_scale)
+ self.connect(self.auto_scale, QtCore.SIGNAL("stateChanged(int)"),
+ self.set_auto_scale)
+ self.right_col_layout.addWidget(self.auto_scale)
+
+ self.add_line_control(self.right_col_layout)
+
+ def set_auto_scale(self, state):
+ if(state):
+ self.top_block.auto_scale(True)
+ else:
+ self.top_block.auto_scale(False)
+
+ def update_samp_rate(self):
+ pass
+
diff --git a/gr-qtgui/apps/plot_form.py b/gr-qtgui/apps/plot_form.py
index f6841811a8..5b034407a8 100644
--- a/gr-qtgui/apps/plot_form.py
+++ b/gr-qtgui/apps/plot_form.py
@@ -27,42 +27,22 @@ except ImportError:
print "Error: Program requires PyQt4."
sys.exit(1)
-class dialog_box(QtGui.QWidget):
+class plot_form(QtGui.QWidget):
def __init__(self, top_block, title=''):
QtGui.QWidget.__init__(self, None)
-
+
self._start = 0
self._end = 0
+ self._y_min = 0
+ self._y_max = 0
self.top_block = top_block
+ self.top_block.gui_y_axis = self.gui_y_axis
self.setWindowTitle(title)
- self.size_val = QtGui.QIntValidator(0, top_block._max_nsamps, self)
-
- self.start_form = QtGui.QFormLayout()
- self.start_edit = QtGui.QLineEdit(self)
- self.start_edit.setMinimumWidth(100)
- self.start_edit.setText(QtCore.QString("%1").arg(top_block._start))
- self.start_edit.setValidator(self.size_val)
- self.start_form.addRow("Start:", self.start_edit)
- self.connect(self.start_edit, QtCore.SIGNAL("returnPressed()"),
- self.update_points)
-
- end = top_block._start + top_block._nsamps
- self.end_form = QtGui.QFormLayout()
- self.end_edit = QtGui.QLineEdit(self)
- self.end_edit.setMinimumWidth(100)
- self.end_edit.setText(QtCore.QString("%1").arg(end))
- self.end_edit.setValidator(self.size_val)
- self.end_form.addRow("End:", self.end_edit)
- self.connect(self.end_edit, QtCore.SIGNAL("returnPressed()"),
- self.update_points)
-
self.layout = QtGui.QGridLayout(self)
- self.layout.addWidget(top_block.get_gui(), 1,0,1,2)
- self.layout.addLayout(self.start_form, 2,0,1,1)
- self.layout.addLayout(self.end_form, 2,1,1,1)
+ self.layout.addWidget(top_block.get_gui(), 1,2,1,2)
# Create a save action
self.save_act = QtGui.QAction("Save", self)
@@ -81,11 +61,241 @@ class dialog_box(QtGui.QWidget):
self.menu.addAction(self.save_act)
self.menu.addAction(self.exit_act)
- self.layout.addWidget(self.menu, 0,0,1,2)
-
- self.resize(800, 500)
+ self.layout.addWidget(self.menu, 0,0,1,4)
+
+ self.left_col_form = QtGui.QFormLayout()
+ self.layout.addLayout(self.left_col_form, 1,0,1,1)
+ self.layout.setColumnStretch(0, 0)
+ self.layout.setColumnStretch(2, 1)
+
+ # Create Edit boxes for X-axis start/stop
+ self.size_val = QtGui.QIntValidator(0, top_block._max_nsamps, self)
+
+ self.start_edit = QtGui.QLineEdit(self)
+ self.start_edit.setMinimumWidth(100)
+ self.start_edit.setMaximumWidth(100)
+ self.start_edit.setText(QtCore.QString("%1").arg(top_block._start))
+ self.start_edit.setValidator(self.size_val)
+ self.left_col_form.addRow("Start:", self.start_edit)
+ self.connect(self.start_edit, QtCore.SIGNAL("returnPressed()"),
+ self.update_xaxis_pos)
+
+ end = top_block._start + top_block._nsamps
+ self.end_edit = QtGui.QLineEdit(self)
+ self.end_edit.setMinimumWidth(100)
+ self.end_edit.setMaximumWidth(100)
+ self.end_edit.setText(QtCore.QString("%1").arg(end))
+ self.end_edit.setValidator(self.size_val)
+ self.left_col_form.addRow("End:", self.end_edit)
+ self.connect(self.end_edit, QtCore.SIGNAL("returnPressed()"),
+ self.update_xaxis_pos)
+
+ # Create a slider to move the position in the file
+ self.posbar = QtGui.QSlider(QtCore.Qt.Horizontal, self)
+ self.posbar.setMaximum(self.top_block._max_nsamps)
+ self.posbar.setPageStep(self.top_block._nsamps)
+ self.connect(self.posbar, QtCore.SIGNAL("valueChanged(int)"),
+ self.update_xaxis_slider)
+ self.layout.addWidget(self.posbar, 2,2,1,1)
+
+ # Create Edit boxes for Y-axis min/max
+ self.y_range_val = QtGui.QDoubleValidator(top_block._y_min,
+ top_block._y_max,
+ 4, self)
- def update_points(self):
+ self.y_max_edit = QtGui.QLineEdit(self)
+ self.y_max_edit.setValidator(self.y_range_val)
+ self.y_max_edit.setMinimumWidth(100)
+ self.y_max_edit.setMaximumWidth(100)
+ self.left_col_form.addRow("Y Max:", self.y_max_edit)
+ self.connect(self.y_max_edit, QtCore.SIGNAL("returnPressed()"),
+ self.update_yaxis_pos)
+
+ self.y_min_edit = QtGui.QLineEdit(self)
+ self.y_min_edit.setValidator(self.y_range_val)
+ self.y_min_edit.setMinimumWidth(100)
+ self.y_min_edit.setMaximumWidth(100)
+ self.left_col_form.addRow("Y Min:", self.y_min_edit)
+ self.connect(self.y_min_edit, QtCore.SIGNAL("returnPressed()"),
+ self.update_yaxis_pos)
+
+ self.grid_check = QtGui.QCheckBox("Grid", self)
+ self.connect(self.grid_check, QtCore.SIGNAL("stateChanged(int)"),
+ self.set_grid_check)
+ self.left_col_form.addWidget(self.grid_check)
+
+ self.gui_y_axis(top_block._y_value-top_block._y_range, top_block._y_value)
+
+ # Create a slider to move the plot's y-axis offset
+ self.ybar = QtGui.QSlider(QtCore.Qt.Vertical, self)
+ self.ybar.setMinimum(self.top_block._y_min)
+ self.ybar.setMaximum(self.top_block._y_max)
+ self.ybar.setPageStep(self.top_block._y_range)
+ self.ybar.setValue(self.top_block._y_value)
+ self.connect(self.ybar, QtCore.SIGNAL("valueChanged(int)"),
+ self.update_yaxis_slider)
+ self.layout.addWidget(self.ybar, 1,1,1,1)
+
+ # Create an edit box for the Sample Rate
+ sr = top_block._samp_rate
+ self.samp_rate_edit = QtGui.QLineEdit(self)
+ self.samp_rate_edit.setMinimumWidth(100)
+ self.samp_rate_edit.setMaximumWidth(100)
+ self.samp_rate_edit.setText(QtCore.QString("%1").arg(sr))
+ self.left_col_form.addRow("Sample Rate:", self.samp_rate_edit)
+ self.connect(self.samp_rate_edit, QtCore.SIGNAL("returnPressed()"),
+ self.update_samp_rate)
+
+ # Create an edit box for the center frequency
+ freq = top_block._center_freq
+ self.freq_edit = QtGui.QLineEdit(self)
+ self.freq_edit.setMinimumWidth(100)
+ self.freq_edit.setMaximumWidth(100)
+ self.freq_edit.setText(QtCore.QString("%1").arg(freq))
+ self.left_col_form.addRow("Frequency:", self.freq_edit)
+ self.connect(self.freq_edit, QtCore.SIGNAL("returnPressed()"),
+ self.update_samp_rate)
+
+ self.resize(1000, 500)
+
+ def add_line_control(self, layout):
+ self._line_tabs = QtGui.QTabWidget()
+
+ self._line_pages = []
+ self._line_forms = []
+ self._label_edit = []
+ self._size_edit = []
+ self._color_edit = []
+ self._style_edit = []
+ self._marker_edit = []
+ self._alpha_edit = []
+ for n in xrange(self.top_block._nsigs):
+ self._line_pages.append(QtGui.QDialog())
+ self._line_forms.append(QtGui.QFormLayout(self._line_pages[-1]))
+
+ label = self.top_block.gui_snk.line_label(n)
+ self._label_edit.append(QtGui.QLineEdit(self))
+ self._label_edit[-1].setMinimumWidth(125)
+ self._label_edit[-1].setMaximumWidth(125)
+ self._label_edit[-1].setText(QtCore.QString("%1").arg(label))
+ self._line_forms[-1].addRow("Label:", self._label_edit[-1])
+ self.connect(self._label_edit[-1], QtCore.SIGNAL("returnPressed()"),
+ self.update_line_label)
+
+ width = self.top_block.gui_snk.line_width(n)
+ self._size_edit.append(QtGui.QLineEdit(self))
+ self._size_edit[-1].setMinimumWidth(100)
+ self._size_edit[-1].setMaximumWidth(100)
+ self._size_edit[-1].setText(QtCore.QString("%1").arg(width))
+ self._line_forms[-1].addRow("Width:", self._size_edit[-1])
+ self.connect(self._size_edit[-1], QtCore.SIGNAL("returnPressed()"),
+ self.update_line_size)
+
+ color = self.top_block.gui_snk.line_color(n)
+ self._color_edit.append(QtGui.QLineEdit(self))
+ self._color_edit[-1].setMinimumWidth(100)
+ self._color_edit[-1].setMaximumWidth(100)
+ self._color_edit[-1].setText(QtCore.QString("%1").arg(color))
+ self._line_forms[-1].addRow("Color:", self._color_edit[-1])
+ self.connect(self._color_edit[-1], QtCore.SIGNAL("returnPressed()"),
+ self.update_line_color)
+
+ self._qtstyles = {"None": QtCore.Qt.NoPen,
+ "Solid": QtCore.Qt.SolidLine,
+ "Dash": QtCore.Qt.DashLine,
+ "Dot": QtCore.Qt.DotLine,
+ "DashDot": QtCore.Qt.DashDotLine,
+ "DashDotDot": QtCore.Qt.DashDotDotLine}
+ self._style_edit.append(QtGui.QComboBox(self))
+ self._style_edit[-1].addItems(["None", "Solid", "Dash",
+ "Dot", "DashDot", "DashDotDot"])
+ self._style_edit[-1].setCurrentIndex(1)
+ self._line_forms[-1].addRow("Style:", self._style_edit[-1])
+ self.connect(self._style_edit[-1],
+ QtCore.SIGNAL("currentIndexChanged(int)"),
+ self.update_line_style)
+
+ # A bit dangerous, this. If QWT ever changes the lineup,
+ # we will have to adjust this, too. But we also can't
+ # really rely on PyQwt right now.
+ self._qwtmarkers = {"None": -1,
+ "Circle": 0,
+ "Rectangle": 1,
+ "Diamond": 2,
+ "Triangle": 3,
+ "Down Triangle": 4,
+ "Left Triangle": 6,
+ "Right Triangle": 7,
+ "Cross": 8,
+ "X-Cross": 9,
+ "Horiz. Line": 10,
+ "Vert. Line": 11,
+ "Star 1": 12,
+ "Star 2": 13,
+ "Hexagon": 14}
+ self._marker_edit.append(QtGui.QComboBox(self))
+ self._marker_edit[-1].addItems(["None", "Circle", "Rectangle", "Diamond",
+ "Triangle", "Down Triangle", "Left Triangle",
+ "Right Triangle", "Cross", "X-Cross",
+ "Horiz. Line", "Vert. Line", "Star 1",
+ "Star 2", "Hexagon"])
+ self._line_forms[-1].addRow("Marker:", self._marker_edit[-1])
+ self.connect(self._marker_edit[-1],
+ QtCore.SIGNAL("currentIndexChanged(int)"),
+ self.update_line_marker)
+
+ alpha_val = QtGui.QDoubleValidator(0, 1.0, 2, self)
+ alpha_val.setTop(1.0)
+ alpha = self.top_block.gui_snk.line_alpha(n)
+ self._alpha_edit.append(QtGui.QLineEdit(self))
+ self._alpha_edit[-1].setMinimumWidth(50)
+ self._alpha_edit[-1].setMaximumWidth(100)
+ self._alpha_edit[-1].setText(QtCore.QString("%1").arg(alpha))
+ self._alpha_edit[-1].setValidator(alpha_val)
+ self._line_forms[-1].addRow("Alpha:", self._alpha_edit[-1])
+ self.connect(self._alpha_edit[-1], QtCore.SIGNAL("returnPressed()"),
+ self.update_line_alpha)
+
+ self._line_tabs.addTab(self._line_pages[-1], "{0}".format(label))
+
+ layout.addWidget(self._line_tabs)
+
+ def update_line_label(self):
+ index = self._line_tabs.currentIndex()
+ label = self._label_edit[index].text()
+ self._line_tabs.setTabText(index, label)
+ self.top_block.gui_snk.set_line_label(index, str(label))
+
+ def update_line_size(self):
+ index = self._line_tabs.currentIndex()
+ width = self._size_edit[index].text().toUInt()[0]
+ self.top_block.gui_snk.set_line_width(index, width)
+ self.update_line_alpha()
+
+ def update_line_color(self):
+ index = self._line_tabs.currentIndex()
+ color = str(self._color_edit[index].text())
+ self.top_block.gui_snk.set_line_color(index, color)
+ self.update_line_alpha()
+
+ def update_line_style(self, s_index):
+ index = self._line_tabs.currentIndex()
+ style_str = self._style_edit[index].itemText(s_index)
+ style = self._qtstyles[str(style_str)]
+ self.top_block.gui_snk.set_line_style(index, int(style))
+
+ def update_line_marker(self, m_index):
+ index = self._line_tabs.currentIndex()
+ marker_str = self._marker_edit[index].itemText(m_index)
+ marker = self._qwtmarkers[str(marker_str)]
+ self.top_block.gui_snk.set_line_marker(index, int(marker))
+
+ def update_line_alpha(self):
+ index = self._line_tabs.currentIndex()
+ alpha = self._alpha_edit[index].text().toDouble()[0]
+ self.top_block.gui_snk.set_line_alpha(index, alpha)
+
+ def update_xaxis_pos(self):
newstart = self.start_edit.text().toUInt()[0]
newend = self.end_edit.text().toUInt()[0]
if(newstart != self._start or newend != self._end):
@@ -99,6 +309,54 @@ class dialog_box(QtGui.QWidget):
self.top_block.reset(newstart, newnsamps)
self._start = newstart
self._end = newend
+ self.posbar.setPageStep(self.top_block._nsamps)
+ self.posbar.setValue(self._start)
+
+ def update_xaxis_slider(self, value):
+ self._start = value
+ self._end = value + self.posbar.pageStep()
+
+ self.start_edit.setText("{0}".format(self._start))
+ self.end_edit.setText("{0}".format(self._end))
+
+ if(value != self.top_block._max_nsamps):
+ self.top_block.reset(self._start, self.posbar.pageStep())
+
+ def update_yaxis_pos(self):
+ newmin = self.y_min_edit.text().toDouble()[0]
+ newmax = self.y_max_edit.text().toDouble()[0]
+ if(newmin != self._y_min or newmax != self._y_max):
+ self._y_min = newmin
+ self._y_max = newmax
+ self.top_block._y_range = newmax - newmin
+ self.ybar.setValue(self._y_max)
+ self.top_block.set_y_axis(self._y_min, self._y_max)
+
+ def update_yaxis_slider(self, value):
+ self.top_block._y_value = value
+ self._y_min = value - self.top_block._y_range
+ self._y_max = value
+
+ self._y_min, self._y_max = self.top_block.set_y_axis(self._y_min, self._y_max)
+
+ self.gui_y_axis(self._y_min, self._y_max)
+
+ def update_samp_rate(self):
+ sr = self.samp_rate_edit.text().toDouble()[0]
+ fr = self.freq_edit.text().toDouble()[0]
+ self.top_block.gui_snk.set_frequency_range(fr, sr)
+ self.top_block.reset(self.top_block._start,
+ self.top_block._nsamps)
+
+ def gui_y_axis(self, ymin, ymax):
+ self.y_min_edit.setText("{0:.4f}".format(ymin))
+ self.y_max_edit.setText("{0:.4f}".format(ymax))
+
+ def set_grid_check(self, state):
+ if(state):
+ self.top_block.gui_snk.enable_grid(True)
+ else:
+ self.top_block.gui_snk.enable_grid(False)
def save_figure(self):
qpix = QtGui.QPixmap.grabWidget(self.top_block.pyWin)
@@ -124,4 +382,3 @@ class dialog_box(QtGui.QWidget):
qpix.save(filename, "TIFF");
else:
qpix.save(filename, "JPEG");
-
diff --git a/gr-qtgui/apps/plot_psd_base.py b/gr-qtgui/apps/plot_psd_base.py
new file mode 100644
index 0000000000..a4a6cb871a
--- /dev/null
+++ b/gr-qtgui/apps/plot_psd_base.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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, blocks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import os, sys
+
+try:
+ from gnuradio import qtgui
+ from PyQt4 import QtGui, QtCore
+ import sip
+except ImportError:
+ print "Error: Program requires PyQt4 and gr-qtgui."
+ sys.exit(1)
+
+try:
+ import scipy
+except ImportError:
+ print "Error: Scipy required (www.scipy.org)."
+ sys.exit(1)
+
+try:
+ from gnuradio.qtgui.plot_form import *
+ from gnuradio.qtgui.plot_base import *
+except ImportError:
+ from plot_form import *
+ from plot_base import *
+
+class plot_base(gr.top_block):
+ def __init__(self, filelist, fc, samp_rate, psdsize, start,
+ nsamples, max_nsamples, avg=1.0):
+ gr.top_block.__init__(self)
+
+ self._filelist = filelist
+ self._center_freq = fc
+ self._samp_rate = samp_rate
+ self._psd_size = psdsize
+ self._start = start
+ self._max_nsamps = max_nsamples
+ self._nsigs = len(self._filelist)
+ self._avg = avg
+ self._nsamps = nsamples
+ self._auto_scale = False
+
+ self._y_min = -200
+ self._y_max = 400
+ self._y_range = 130
+ self._y_value = 10
+
+ self._is_setup = False
+
+ self.qapp = QtGui.QApplication(sys.argv)
+
+ def setup(self):
+ self.skip = gr.skiphead(self.dsize, self._start)
+
+ n = 0
+ self.srcs = list()
+ self._data_min = sys.maxint
+ self._data_max = -sys.maxint - 1
+ for f in self._filelist:
+ data,_min,_max = self.read_samples(f, self._start,
+ self._nsamps, self._psd_size)
+ if(_min < self._data_min):
+ self._data_min = _min
+ if(_max > self._data_max):
+ self._data_max = _max
+
+ self.srcs.append(self.src_type(data))
+
+ # Set default labels based on file names
+ fname = f.split("/")[-1]
+ self.gui_snk.set_line_label(n, "{0}".format(fname))
+ n += 1
+
+ self.connect(self.srcs[0], self.skip)
+ self.connect(self.skip, (self.gui_snk, 0))
+
+ for i,s in enumerate(self.srcs[1:]):
+ self.connect(s, (self.gui_snk, i+1))
+
+ self.gui_snk.set_update_time(0)
+ self.gui_snk.enable_menu(False)
+
+ # Get Python Qt references
+ pyQt = self.gui_snk.pyqwidget()
+ self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
+
+ self._is_setup = True
+
+ def is_setup(self):
+ return self._is_setup
+
+ def set_y_axis(self, y_min, y_max):
+ self.gui_snk.set_y_axis(y_min, y_max)
+ return y_min, y_max
+
+ def get_gui(self):
+ if(self.is_setup()):
+ return self.pyWin
+ else:
+ return None
+
+ def reset(self, newstart, newnsamps):
+ self.stop()
+ self.wait()
+
+ self._start = newstart
+
+ self._data_min = sys.maxint
+ self._data_max = -sys.maxint - 1
+ for s,f in zip(self.srcs, self._filelist):
+ data,_min,_max = self.read_samples(f, self._start, newnsamps, self._psd_size)
+ if(_min < self._data_min):
+ self._data_min = _min
+ if(_max > self._data_max):
+ self._data_max = _max
+
+ s.set_data(data)
+
+ self.start()
+
+def setup_options(desc):
+ parser = OptionParser(option_class=eng_option, description=desc,
+ conflict_handler="resolve")
+ parser.add_option("-N", "--nsamples", type="int", default=1000000,
+ help="Set the number of samples to display [default=prints entire file]")
+ parser.add_option("-S", "--start", type="int", default=0,
+ help="Starting sample number [default=%default]")
+ parser.add_option("-L", "--psd-size", type="int", default=2048,
+ help="Set the FFT size of the PSD [default=%default]")
+ parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0,
+ help="Set the center frequency of the signal [default=%default]")
+ parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
+ help="Set the sample rate of the signal [default=%default]")
+ parser.add_option("-a", "--average", type="float", default=1.0,
+ help="Set amount of averaging (smaller=more averaging) [default=%default]")
+ (options, args) = parser.parse_args()
+
+ if(len(args) < 1):
+ parser.print_help()
+ sys.exit(0)
+ return (options,args)
diff --git a/gr-qtgui/apps/plot_psd_form.py b/gr-qtgui/apps/plot_psd_form.py
new file mode 100644
index 0000000000..262734bd67
--- /dev/null
+++ b/gr-qtgui/apps/plot_psd_form.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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.
+#
+
+import sys
+from gnuradio import filter
+
+try:
+ from PyQt4 import QtGui, QtCore
+ import sip
+except ImportError:
+ print "Error: Program requires PyQt4."
+ sys.exit(1)
+
+try:
+ from gnuradio.qtgui.plot_from import plot_form
+except ImportError:
+ from plot_form import plot_form
+
+class plot_psd_form(plot_form):
+ def __init__(self, top_block, title=''):
+ plot_form.__init__(self, top_block, title)
+
+ self.right_col_layout = QtGui.QVBoxLayout()
+ self.right_col_form = QtGui.QFormLayout()
+ self.right_col_layout.addLayout(self.right_col_form)
+ self.layout.addLayout(self.right_col_layout, 1,4,1,1)
+
+ self.psd_size_val = QtGui.QIntValidator(0, 2**18, self)
+ self.psd_size_edit = QtGui.QLineEdit(self)
+ self.psd_size_edit.setMinimumWidth(50)
+ self.psd_size_edit.setMaximumWidth(100)
+ self.psd_size_edit.setText(QtCore.QString("%1").arg(top_block._psd_size))
+ self.psd_size_edit.setValidator(self.psd_size_val)
+ self.right_col_form.addRow("FFT:", self.psd_size_edit)
+ self.connect(self.psd_size_edit, QtCore.SIGNAL("returnPressed()"),
+ self.update_psd_size)
+
+ self.psd_win_combo = QtGui.QComboBox(self)
+ self.psd_win_combo.addItems(["None", "Hamming", "Hann", "Blackman",
+ "Rectangular", "Kaiser", "Blackman-harris"])
+ self.psd_win_combo.setCurrentIndex(self.top_block.gui_snk.fft_window()+1)
+ self.right_col_form.addRow("Window:", self.psd_win_combo)
+ self.connect(self.psd_win_combo,
+ QtCore.SIGNAL("currentIndexChanged(int)"),
+ self.update_psd_win)
+
+ self.psd_avg_val = QtGui.QDoubleValidator(0, 1.0, 4, self)
+ self.psd_avg_edit = QtGui.QLineEdit(self)
+ self.psd_avg_edit.setMinimumWidth(50)
+ self.psd_avg_edit.setMaximumWidth(100)
+ self.psd_avg_edit.setText(QtCore.QString("%1").arg(top_block._avg))
+ self.psd_avg_edit.setValidator(self.psd_avg_val)
+ self.right_col_form.addRow("Average:", self.psd_avg_edit)
+ self.connect(self.psd_avg_edit, QtCore.SIGNAL("returnPressed()"),
+ self.update_psd_avg)
+
+ self.add_line_control(self.right_col_layout)
+
+ def update_psd_size(self):
+ newpsdsize = self.psd_size_edit.text().toInt()[0]
+ if(newpsdsize != self.top_block._psd_size):
+ self.top_block.gui_snk.set_fft_size(newpsdsize)
+ self.top_block._psd_size = newpsdsize
+ self.top_block.reset(self.top_block._start,
+ self.top_block._nsamps)
+
+ def update_psd_win(self, index):
+ self.top_block.gui_snk.set_fft_window(index-1)
+ self.top_block.reset(self.top_block._start,
+ self.top_block._nsamps)
+
+ def update_psd_avg(self):
+ newpsdavg = self.psd_avg_edit.text().toDouble()[0]
+ if(newpsdavg != self.top_block._avg):
+ self.top_block.gui_snk.set_fft_average(newpsdavg)
+ self.top_block._avg = newpsdavg
+ self.top_block.reset(self.top_block._start,
+ self.top_block._nsamps)
+
diff --git a/gr-qtgui/apps/plot_spectrogram_base.py b/gr-qtgui/apps/plot_spectrogram_base.py
new file mode 100644
index 0000000000..adfbfd032f
--- /dev/null
+++ b/gr-qtgui/apps/plot_spectrogram_base.py
@@ -0,0 +1,168 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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, blocks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import os, sys
+
+try:
+ from gnuradio import qtgui
+ from PyQt4 import QtGui, QtCore
+ import sip
+except ImportError:
+ print "Error: Program requires PyQt4 and gr-qtgui."
+ sys.exit(1)
+
+try:
+ import scipy
+except ImportError:
+ print "Error: Scipy required (www.scipy.org)."
+ sys.exit(1)
+
+try:
+ from gnuradio.qtgui.plot_form import *
+ from gnuradio.qtgui.plot_base import *
+except ImportError:
+ from plot_form import *
+ from plot_base import *
+
+class plot_base(gr.top_block):
+ def __init__(self, filelist, fc, samp_rate, psdsize, start,
+ nsamples, max_nsamples, avg=1.0):
+ gr.top_block.__init__(self)
+
+ self._filelist = filelist
+ self._center_freq = fc
+ self._samp_rate = samp_rate
+ self._psd_size = psdsize
+ self._start = start
+ self._max_nsamps = max_nsamples
+ self._nsigs = len(self._filelist)
+ self._avg = avg
+ self._nsamps = nsamples
+ self._auto_scale = False
+
+ self._y_min = -200
+ self._y_max = 400
+ self._y_range = 130
+ self._y_value = 10
+
+ self._is_setup = False
+
+ self.qapp = QtGui.QApplication(sys.argv)
+
+ def setup(self):
+ self.skip = gr.skiphead(self.dsize, self._start)
+
+ n = 0
+ self.srcs = list()
+ self._data_min = sys.maxint
+ self._data_max = -sys.maxint - 1
+ for f in self._filelist:
+ data,_min,_max = self.read_samples(f, self._start,
+ self._nsamps, self._psd_size)
+ if(_min < self._data_min):
+ self._data_min = _min
+ if(_max > self._data_max):
+ self._data_max = _max
+
+ self.srcs.append(self.src_type(data))
+
+ # Set default labels based on file names
+ fname = f.split("/")[-1]
+ self.gui_snk.set_line_label(n, "{0}".format(fname))
+ n += 1
+
+ self.connect(self.srcs[0], self.skip)
+ self.connect(self.skip, (self.gui_snk, 0))
+
+ for i,s in enumerate(self.srcs[1:]):
+ self.connect(s, (self.gui_snk, i+1))
+
+ self.gui_snk.set_update_time(0);
+ self.gui_snk.enable_menu(False)
+ self.gui_snk.set_fft_average(self._avg)
+
+ # Get Python Qt references
+ pyQt = self.gui_snk.pyqwidget()
+ self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
+
+ self._is_setup = True
+
+ def is_setup(self):
+ return self._is_setup
+
+ def set_y_axis(self, y_min, y_max):
+ self.gui_snk.set_intensity_range(y_min, y_max)
+ return y_min, y_max
+
+ def get_gui(self):
+ if(self.is_setup()):
+ return self.pyWin
+ else:
+ return None
+
+ def reset(self, newstart, newnsamps):
+ self.stop()
+ self.wait()
+ self.gui_snk.clear_data()
+
+ self._start = newstart
+ self._nsamps = newnsamps
+
+ self._data_min = sys.maxint
+ self._data_max = -sys.maxint - 1
+ for s,f in zip(self.srcs, self._filelist):
+ data,_min,_max = self.read_samples(f, self._start, newnsamps, self._psd_size)
+ if(_min < self._data_min):
+ self._data_min = _min
+ if(_max > self._data_max):
+ self._data_max = _max
+
+ s.set_data(data)
+
+ self.start()
+
+def setup_options(desc):
+ parser = OptionParser(option_class=eng_option, description=desc,
+ conflict_handler="resolve")
+ parser.add_option("-N", "--nsamples", type="int", default=1000000,
+ help="Set the number of samples to display [default=%default]")
+ parser.add_option("-S", "--start", type="int", default=0,
+ help="Starting sample number [default=%default]")
+ parser.add_option("-L", "--psd-size", type="int", default=2048,
+ help="Set the FFT size of the PSD [default=%default]")
+ parser.add_option("-f", "--center-frequency", type="eng_float", default=0.0,
+ help="Set the center frequency of the signal [default=%default]")
+ parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
+ help="Set the sample rate of the signal [default=%default]")
+ parser.add_option("-a", "--average", type="float", default=1.0,
+ help="Set amount of averaging (smaller=more averaging) [default=%default]")
+ (options, args) = parser.parse_args()
+
+ if(len(args) < 1):
+ parser.print_help()
+ sys.exit(0)
+
+ return (options, args)
+
diff --git a/gr-qtgui/apps/plot_spectrogram_form.py b/gr-qtgui/apps/plot_spectrogram_form.py
new file mode 100644
index 0000000000..7f8361e6b1
--- /dev/null
+++ b/gr-qtgui/apps/plot_spectrogram_form.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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.
+#
+
+import sys
+from gnuradio import filter
+
+try:
+ from PyQt4 import QtGui, QtCore
+ import sip
+except ImportError:
+ print "Error: Program requires PyQt4."
+ sys.exit(1)
+
+try:
+ from gnuradio.qtgui.plot_from import plot_form
+except ImportError:
+ from plot_form import plot_form
+
+class plot_spectrogram_form(plot_form):
+ def __init__(self, top_block, title=''):
+ plot_form.__init__(self, top_block, title)
+
+ self.right_col_layout = QtGui.QVBoxLayout()
+ self.right_col_form = QtGui.QFormLayout()
+ self.right_col_layout.addLayout(self.right_col_form)
+ self.layout.addLayout(self.right_col_layout, 1,4,1,1)
+
+ self.psd_size_val = QtGui.QIntValidator(0, 2**18, self)
+ self.psd_size_edit = QtGui.QLineEdit(self)
+ self.psd_size_edit.setMinimumWidth(50)
+ self.psd_size_edit.setMaximumWidth(100)
+ self.psd_size_edit.setText(QtCore.QString("%1").arg(top_block._psd_size))
+ self.psd_size_edit.setValidator(self.psd_size_val)
+ self.right_col_form.addRow("FFT Size:", self.psd_size_edit)
+ self.connect(self.psd_size_edit, QtCore.SIGNAL("returnPressed()"),
+ self.update_psd_size)
+
+ self.psd_win_combo = QtGui.QComboBox(self)
+ self.psd_win_combo.addItems(["None", "Hamming", "Hann", "Blackman",
+ "Rectangular", "Kaiser", "Blackman-harris"])
+ self.psd_win_combo.setCurrentIndex(self.top_block.gui_snk.fft_window()+1)
+ self.right_col_form.addRow("Window:", self.psd_win_combo)
+ self.connect(self.psd_win_combo,
+ QtCore.SIGNAL("currentIndexChanged(int)"),
+ self.update_psd_win)
+
+ self.psd_avg_val = QtGui.QDoubleValidator(0, 1.0, 4, self)
+ self.psd_avg_edit = QtGui.QLineEdit(self)
+ self.psd_avg_edit.setMinimumWidth(50)
+ self.psd_avg_edit.setMaximumWidth(100)
+ self.psd_avg_edit.setText(QtCore.QString("%1").arg(top_block._avg))
+ self.psd_avg_edit.setValidator(self.psd_avg_val)
+ self.right_col_form.addRow("Average:", self.psd_avg_edit)
+ self.connect(self.psd_avg_edit, QtCore.SIGNAL("returnPressed()"),
+ self.update_psd_avg)
+
+ self.autoscale_button = QtGui.QPushButton("Auto Scale", self)
+ self.autoscale_button.setMaximumWidth(100)
+ self.right_col_layout.addWidget(self.autoscale_button)
+ self.connect(self.autoscale_button, QtCore.SIGNAL("clicked()"),
+ self.spectrogram_auto_scale)
+
+ self.add_spectrogram_control(self.right_col_layout)
+
+ def update_psd_size(self):
+ newpsdsize = self.psd_size_edit.text().toInt()[0]
+ if(newpsdsize != self.top_block._psd_size):
+ self.top_block.gui_snk.set_fft_size(newpsdsize)
+ self.top_block._psd_size = newpsdsize
+ self.top_block.reset(self.top_block._start,
+ self.top_block._nsamps)
+
+ def update_psd_win(self, index):
+ self.top_block.gui_snk.set_fft_window(index-1)
+ self.top_block.reset(self.top_block._start,
+ self.top_block._nsamps)
+
+ def update_psd_avg(self):
+ newpsdavg = self.psd_avg_edit.text().toDouble()[0]
+ if(newpsdavg != self.top_block._avg):
+ self.top_block.gui_snk.set_fft_average(newpsdavg)
+ self.top_block._avg = newpsdavg
+ self.top_block.reset(self.top_block._start,
+ self.top_block._nsamps)
+
+ def add_spectrogram_control(self, layout):
+ self._line_tabs = QtGui.QTabWidget()
+
+ self._line_pages = []
+ self._line_forms = []
+ self._label_edit = []
+ self._size_edit = []
+ self._color_edit = []
+ self._style_edit = []
+ self._marker_edit = []
+ self._alpha_edit = []
+ for n in xrange(self.top_block._nsigs):
+ self._line_pages.append(QtGui.QDialog())
+ self._line_forms.append(QtGui.QFormLayout(self._line_pages[-1]))
+
+ label = self.top_block.gui_snk.line_label(n)
+ self._label_edit.append(QtGui.QLineEdit(self))
+ self._label_edit[-1].setMinimumWidth(125)
+ self._label_edit[-1].setMaximumWidth(125)
+ self._label_edit[-1].setText(QtCore.QString("%1").arg(label))
+ self._line_forms[-1].addRow("Label:", self._label_edit[-1])
+ self.connect(self._label_edit[-1], QtCore.SIGNAL("returnPressed()"),
+ self.update_line_label)
+
+ self._qtcolormaps = ["Multi Color", "White Hot",
+ "Black Hot", "Incandescent"]
+ self._color_edit.append(QtGui.QComboBox(self))
+ self._color_edit[-1].addItems(self._qtcolormaps)
+ self._line_forms[-1].addRow("Color Map:", self._color_edit[-1])
+ self.connect(self._color_edit[-1],
+ QtCore.SIGNAL("currentIndexChanged(int)"),
+ self.update_color_map)
+
+ alpha_val = QtGui.QDoubleValidator(0, 1.0, 2, self)
+ alpha_val.setTop(1.0)
+ alpha = self.top_block.gui_snk.line_alpha(n)
+ self._alpha_edit.append(QtGui.QLineEdit(self))
+ self._alpha_edit[-1].setMinimumWidth(50)
+ self._alpha_edit[-1].setMaximumWidth(100)
+ self._alpha_edit[-1].setText(QtCore.QString("%1").arg(alpha))
+ self._alpha_edit[-1].setValidator(alpha_val)
+ self._line_forms[-1].addRow("Alpha:", self._alpha_edit[-1])
+ self.connect(self._alpha_edit[-1], QtCore.SIGNAL("returnPressed()"),
+ self.update_line_alpha)
+
+ self._line_tabs.addTab(self._line_pages[-1], "{0}".format(label))
+
+ layout.addWidget(self._line_tabs)
+
+ def update_color_map(self, c_index):
+ index = self._line_tabs.currentIndex()
+ self.top_block.gui_snk.set_color_map(index, c_index)
+ self.update_line_alpha()
+
+ def spectrogram_auto_scale(self):
+ self.top_block.gui_snk.auto_scale()
+ _min = self.top_block.gui_snk.min_intensity(0)
+ _max = self.top_block.gui_snk.max_intensity(0)
+ if(self.gui_y_axis):
+ self.gui_y_axis(_min, _max)
diff --git a/gr-qtgui/apps/plot_time_base.py b/gr-qtgui/apps/plot_time_base.py
new file mode 100644
index 0000000000..c80bace1b6
--- /dev/null
+++ b/gr-qtgui/apps/plot_time_base.py
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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, blocks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import os, sys
+
+try:
+ from gnuradio import qtgui
+ from PyQt4 import QtGui, QtCore
+ import sip
+except ImportError:
+ print "Error: Program requires PyQt4 and gr-qtgui."
+ sys.exit(1)
+
+try:
+ import scipy
+except ImportError:
+ print "Error: Scipy required (www.scipy.org)."
+ sys.exit(1)
+
+try:
+ from gnuradio.qtgui.plot_form import *
+ from gnuradio.qtgui.plot_base import *
+except ImportError:
+ from plot_form import *
+ from plot_base import *
+
+class plot_base(gr.top_block):
+ def __init__(self, filelist, samp_rate, start,
+ nsamples, max_nsamples,
+ auto_scale):
+ gr.top_block.__init__(self)
+
+ self._filelist = filelist
+ self._samp_rate = samp_rate
+ self._center_freq = 0
+ self._start = start
+ self._max_nsamps = max_nsamples
+ self._nsigs = len(self._filelist)
+ self._auto_scale = auto_scale
+ self._nsamps = nsamples
+ self._is_setup = False
+
+ self._y_min = -20
+ self._y_max = 20
+ self._y_range = 2
+ self._y_value = 1
+ self.gui_y_axis = None
+
+ self.qapp = QtGui.QApplication(sys.argv)
+
+ def setup(self):
+ self.skip = gr.skiphead(self.dsize, self._start)
+
+ n = 0
+ self.srcs = list()
+ self._data_min = sys.maxint
+ self._data_max = -sys.maxint - 1
+ for f in self._filelist:
+ data,_min,_max = self.read_samples(f, self._start, self._nsamps)
+ if(_min < self._data_min):
+ self._data_min = _min
+ if(_max > self._data_max):
+ self._data_max = _max
+
+ self.srcs.append(self.src_type(data))
+
+ # Set default labels based on file names
+ fname = f.split("/")[-1]
+ if(type(self.gui_snk) == qtgui.time_sink_c_sptr):
+ self.gui_snk.set_line_label(n, "Re{{{0}}}".format(fname))
+ self.gui_snk.set_line_label(n+1, "Im{{{0}}}".format(fname))
+ n += 2
+ else:
+ self.gui_snk.set_line_label(n, "{0}".format(fname))
+ n += 1
+
+ self.connect(self.srcs[0], self.skip)
+ self.connect(self.skip, (self.gui_snk, 0))
+
+ for i,s in enumerate(self.srcs[1:]):
+ self.connect(s, (self.gui_snk, i+1))
+
+ self.gui_snk.set_update_time(0)
+ self.gui_snk.enable_menu(False)
+ self.auto_scale(self._auto_scale)
+
+ # Get Python Qt references
+ pyQt = self.gui_snk.pyqwidget()
+ self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
+
+ self._is_setup = True
+
+ def is_setup(self):
+ return self._is_setup
+
+ def set_y_axis(self, y_min, y_max):
+ self.gui_snk.set_y_axis(y_min, y_max)
+ return y_min, y_max
+
+ def get_gui(self):
+ if(self.is_setup()):
+ return self.pyWin
+ else:
+ return None
+
+ def reset(self, newstart, newnsamps):
+ self.stop()
+ self.wait()
+
+ self._start = newstart
+
+ self._data_min = sys.maxint
+ self._data_max = -sys.maxint - 1
+ for s,f in zip(self.srcs, self._filelist):
+ data,_min,_max = self.read_samples(f, self._start, newnsamps)
+ if(_min < self._data_min):
+ self._data_min = _min
+ if(_max > self._data_max):
+ self._data_max = _max
+
+ s.set_data(data)
+ if(len(data) < newnsamps):
+ newnsamps = len(data)
+
+ self.auto_scale(self._auto_scale)
+
+ self._nsamps = newnsamps
+ self.gui_snk.set_nsamps(self._nsamps)
+
+ self.start()
+
+ def auto_scale(self, state):
+ if(state > 0):
+ self.gui_snk.set_y_axis(self._data_min, self._data_max)
+ self._auto_scale = True
+ self._y_value = self._data_max
+ self._y_range = self._data_max - self._data_min
+ self._y_min = 10*self._data_min
+ self._y_max = 10*self._data_max
+
+ if(self.gui_y_axis):
+ self.gui_y_axis(self._data_min, self._data_max)
+ else:
+ self._auto_scale = False
+
+def setup_options(desc):
+ parser = OptionParser(option_class=eng_option, description=desc,
+ conflict_handler="resolve")
+ parser.add_option("-N", "--nsamples", type="int", default=1000000,
+ help="Set the number of samples to display [default=%default]")
+ parser.add_option("-S", "--start", type="int", default=0,
+ help="Starting sample number [default=%default]")
+ parser.add_option("-r", "--sample-rate", type="eng_float", default=1.0,
+ help="Set the sample rate of the signal [default=%default]")
+ parser.add_option("", "--no-auto-scale", action="store_true", default=False,
+ help="Do not auto-scale the plot [default=%default]")
+ (options,args) = parser.parse_args()
+ if(len(args) < 1):
+ parser.print_help()
+ sys.exit(0)
+ return (options,args)
+
diff --git a/gr-qtgui/apps/plot_time_form.py b/gr-qtgui/apps/plot_time_form.py
new file mode 100644
index 0000000000..cff3ad6857
--- /dev/null
+++ b/gr-qtgui/apps/plot_time_form.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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.
+#
+
+import sys
+from gnuradio import filter
+
+try:
+ from PyQt4 import QtGui, QtCore
+ import sip
+except ImportError:
+ print "Error: Program requires PyQt4."
+ sys.exit(1)
+
+try:
+ from gnuradio.qtgui.plot_from import plot_form
+except ImportError:
+ from plot_form import plot_form
+
+class plot_time_form(plot_form):
+ def __init__(self, top_block, title=''):
+ plot_form.__init__(self, top_block, title)
+
+ self.right_col_layout = QtGui.QVBoxLayout()
+ self.right_col_form = QtGui.QFormLayout()
+ self.right_col_layout.addLayout(self.right_col_form)
+ self.layout.addLayout(self.right_col_layout, 1,4,1,1)
+
+ self.auto_scale = QtGui.QCheckBox("Auto Scale", self)
+ if(self.top_block._auto_scale):
+ self.auto_scale.setChecked(self.top_block._auto_scale)
+ self.connect(self.auto_scale, QtCore.SIGNAL("stateChanged(int)"),
+ self.set_auto_scale)
+ self.right_col_layout.addWidget(self.auto_scale)
+
+ self.stem = QtGui.QCheckBox("Stem", self)
+ self.connect(self.stem, QtCore.SIGNAL("stateChanged(int)"),
+ self.toggle_stem)
+ self.right_col_layout.addWidget(self.stem)
+
+ self.add_line_control(self.right_col_layout)
+
+ def set_auto_scale(self, state):
+ if(state):
+ self.top_block.auto_scale(True)
+ else:
+ self.top_block.auto_scale(False)
+
+ def toggle_stem(self, state):
+ self.top_block.gui_snk.toggle_stem_plot()
+ if(state):
+ index = self._qwtmarkers.keys().index('Circle')
+ else:
+ index = self._qwtmarkers.keys().index('None')
+ for n in xrange(self.top_block._nsigs):
+ self._marker_edit[n].setCurrentIndex(index)
+
+ def update_samp_rate(self):
+ sr = self.samp_rate_edit.text().toDouble()[0]
+ self.top_block.gui_snk.set_samp_rate(sr)
+
diff --git a/gr-qtgui/examples/pyqt_waterfall_c.py b/gr-qtgui/examples/pyqt_waterfall_c.py
index 3fce9b9a5a..407e8d1bb0 100755
--- a/gr-qtgui/examples/pyqt_waterfall_c.py
+++ b/gr-qtgui/examples/pyqt_waterfall_c.py
@@ -146,10 +146,12 @@ class my_top_block(gr.top_block):
Rs = 8000
f1 = 100
- f2 = 200
+ f2 = 2000
npts = 2048
+ taps = filter.firdes.complex_band_pass_2(1, Rs, 1500, 2500, 100, 60)
+
self.qapp = QtGui.QApplication(sys.argv)
ss = open('dark.qss')
sstext = ss.read()
@@ -161,13 +163,15 @@ class my_top_block(gr.top_block):
src = blocks.add_cc()
channel = channels.channel_model(0.01)
thr = gr.throttle(gr.sizeof_gr_complex, 100*npts)
- self.snk1 = qtgui.waterfall_sink_c(npts, filter.firdes.WIN_BLACKMAN_hARRIS,
+ filt = filter.fft_filter_ccc(1, taps)
+ self.snk1 = qtgui.waterfall_sink_c(npts, gr.firdes.WIN_BLACKMAN_hARRIS,
0, Rs,
- "Complex Waterfall Example")
+ "Complex Waterfall Example", 2)
self.connect(src1, (src,0))
self.connect(src2, (src,1))
self.connect(src, channel, thr, (self.snk1, 0))
+ self.connect(thr, filt, (self.snk1, 1))
self.ctrl_win = control_box()
self.ctrl_win.attach_signal1(src1)
diff --git a/gr-qtgui/examples/pyqt_waterfall_f.py b/gr-qtgui/examples/pyqt_waterfall_f.py
index 1c4063e31b..8843f19528 100755
--- a/gr-qtgui/examples/pyqt_waterfall_f.py
+++ b/gr-qtgui/examples/pyqt_waterfall_f.py
@@ -140,7 +140,7 @@ class my_top_block(gr.top_block):
Rs = 8000
f1 = 100
- f2 = 200
+ f2 = 2000
npts = 2048
@@ -152,11 +152,12 @@ class my_top_block(gr.top_block):
thr = gr.throttle(gr.sizeof_float, 100*npts)
self.snk1 = qtgui.waterfall_sink_f(npts, filter.firdes.WIN_BLACKMAN_hARRIS,
0, Rs,
- "Real Waterfall Example")
+ "Real Waterfall Example", 2)
self.connect(src1, (src,0))
self.connect(src2, (src,1))
self.connect(src, thr, (self.snk1, 0))
+ self.connect(src1, (self.snk1, 1))
self.ctrl_win = control_box()
self.ctrl_win.attach_signal1(src1)
diff --git a/gr-qtgui/include/qtgui/const_sink_c.h b/gr-qtgui/include/qtgui/const_sink_c.h
index 49d64af79c..9a9783bed4 100644
--- a/gr-qtgui/include/qtgui/const_sink_c.h
+++ b/gr-qtgui/include/qtgui/const_sink_c.h
@@ -27,8 +27,7 @@
#include <qtgui/api.h>
#include <gr_sync_block.h>
#include <qapplication.h>
-#include <qwt_symbol.h>
-
+#include <filter/firdes.h>
namespace gr {
namespace qtgui {
@@ -55,7 +54,7 @@ namespace gr {
*/
static sptr make(int size,
const std::string &name,
- int nconnections,
+ int nconnections=1,
QWidget *parent=NULL);
virtual void exec_() = 0;
@@ -69,12 +68,22 @@ namespace gr {
virtual void set_line_label(int which, const std::string &label) = 0;
virtual void set_line_color(int which, const std::string &color) = 0;
virtual void set_line_width(int which, int width) = 0;
- virtual void set_line_style(int which, Qt::PenStyle style) = 0;
- virtual void set_line_marker(int which, QwtSymbol::Style marker) = 0;
+ virtual void set_line_style(int which, int style) = 0;
+ virtual void set_line_marker(int which, int marker) = 0;
virtual void set_nsamps(const int newsize) = 0;
+ virtual void set_line_alpha(int which, double alpha) = 0;
+
+ virtual std::string title() = 0;
+ virtual std::string line_label(int which) = 0;
+ virtual std::string line_color(int which) = 0;
+ virtual int line_width(int which) = 0;
+ virtual int line_style(int which) = 0;
+ virtual int line_marker(int which) = 0;
+ virtual double line_alpha(int which) = 0;
virtual void set_size(int width, int height) = 0;
+ virtual void enable_menu(bool en=true) = 0;
virtual int nsamps() const = 0;
virtual void reset() = 0;
diff --git a/gr-qtgui/include/qtgui/freq_sink_c.h b/gr-qtgui/include/qtgui/freq_sink_c.h
index 391a27c04a..37a12440a0 100644
--- a/gr-qtgui/include/qtgui/freq_sink_c.h
+++ b/gr-qtgui/include/qtgui/freq_sink_c.h
@@ -27,7 +27,7 @@
#include <qtgui/api.h>
#include <gr_sync_block.h>
#include <qapplication.h>
-#include <qwt_symbol.h>
+#include <filter/firdes.h>
namespace gr {
namespace qtgui {
@@ -62,7 +62,7 @@ namespace gr {
static sptr make(int fftsize, int wintype,
double fc, double bw,
const std::string &name,
- int nconnections,
+ int nconnections=1,
QWidget *parent=NULL);
virtual void exec_() = 0;
@@ -72,20 +72,34 @@ namespace gr {
virtual int fft_size() const = 0;
virtual void set_fft_average(const float fftavg) = 0;
virtual float fft_average() const = 0;
+ virtual void set_fft_window(const gr::filter::firdes::win_type win) = 0;
+ virtual gr::filter::firdes::win_type fft_window() = 0;
virtual void set_frequency_range(const double centerfreq, const double bandwidth) = 0;
virtual void set_y_axis(double min, double max) = 0;
virtual void set_update_time(double t) = 0;
+
virtual void set_title(const std::string &title) = 0;
virtual void set_line_label(int which, const std::string &label) = 0;
virtual void set_line_color(int which, const std::string &color) = 0;
virtual void set_line_width(int which, int width) = 0;
- virtual void set_line_style(int which, Qt::PenStyle style) = 0;
- virtual void set_line_marker(int which, QwtSymbol::Style marker) = 0;
+ virtual void set_line_style(int which, int style) = 0;
+ virtual void set_line_marker(int which, int marker) = 0;
+ virtual void set_line_alpha(int which, double alpha) = 0;
+
+ virtual std::string title() = 0;
+ virtual std::string line_label(int which) = 0;
+ virtual std::string line_color(int which) = 0;
+ virtual int line_width(int which) = 0;
+ virtual int line_style(int which) = 0;
+ virtual int line_marker(int which) = 0;
+ virtual double line_alpha(int which) = 0;
virtual void set_size(int width, int height) = 0;
+ virtual void enable_menu(bool en=true) = 0;
+ virtual void enable_grid(bool en=true) = 0;
virtual void reset() = 0;
QApplication *d_qApplication;
diff --git a/gr-qtgui/include/qtgui/freq_sink_f.h b/gr-qtgui/include/qtgui/freq_sink_f.h
index 3f4b9362b6..4682f73c10 100644
--- a/gr-qtgui/include/qtgui/freq_sink_f.h
+++ b/gr-qtgui/include/qtgui/freq_sink_f.h
@@ -27,7 +27,7 @@
#include <qtgui/api.h>
#include <gr_sync_block.h>
#include <qapplication.h>
-#include <qwt_symbol.h>
+#include <filter/firdes.h>
namespace gr {
namespace qtgui {
@@ -62,7 +62,7 @@ namespace gr {
static sptr make(int fftsize, int wintype,
double fc, double bw,
const std::string &name,
- int nconnections,
+ int nconnections=1,
QWidget *parent=NULL);
virtual void exec_() = 0;
@@ -72,6 +72,8 @@ namespace gr {
virtual int fft_size() const = 0;
virtual void set_fft_average(const float fftavg) = 0;
virtual float fft_average() const = 0;
+ virtual void set_fft_window(const gr::filter::firdes::win_type win) = 0;
+ virtual gr::filter::firdes::win_type fft_window() = 0;
virtual void set_frequency_range(const double centerfreq, const double bandwidth) = 0;
virtual void set_y_axis(double min, double max) = 0;
@@ -81,11 +83,22 @@ namespace gr {
virtual void set_line_label(int which, const std::string &label) = 0;
virtual void set_line_color(int which, const std::string &color) = 0;
virtual void set_line_width(int which, int width) = 0;
- virtual void set_line_style(int which, Qt::PenStyle style) = 0;
- virtual void set_line_marker(int which, QwtSymbol::Style marker) = 0;
+ virtual void set_line_style(int which, int style) = 0;
+ virtual void set_line_marker(int which, int marker) = 0;
+ virtual void set_line_alpha(int which, double alpha) = 0;
+
+ virtual std::string title() = 0;
+ virtual std::string line_label(int which) = 0;
+ virtual std::string line_color(int which) = 0;
+ virtual int line_width(int which) = 0;
+ virtual int line_style(int which) = 0;
+ virtual int line_marker(int which) = 0;
+ virtual double line_alpha(int which) = 0;
virtual void set_size(int width, int height) = 0;
+ virtual void enable_menu(bool en=true) = 0;
+ virtual void enable_grid(bool en=true) = 0;
virtual void reset() = 0;
QApplication *d_qApplication;
diff --git a/gr-qtgui/include/qtgui/time_sink_c.h b/gr-qtgui/include/qtgui/time_sink_c.h
index 972a720a65..ef72f7df58 100644
--- a/gr-qtgui/include/qtgui/time_sink_c.h
+++ b/gr-qtgui/include/qtgui/time_sink_c.h
@@ -27,7 +27,6 @@
#include <qtgui/api.h>
#include <gr_sync_block.h>
#include <qapplication.h>
-#include <qwt_symbol.h>
namespace gr {
namespace qtgui {
@@ -60,7 +59,7 @@ namespace gr {
*/
static sptr make(int size, double samp_rate,
const std::string &name,
- int nconnections,
+ int nconnections=1,
QWidget *parent=NULL);
virtual void exec_() = 0;
@@ -72,13 +71,25 @@ namespace gr {
virtual void set_line_label(int which, const std::string &label) = 0;
virtual void set_line_color(int which, const std::string &color) = 0;
virtual void set_line_width(int which, int width) = 0;
- virtual void set_line_style(int which, Qt::PenStyle style) = 0;
- virtual void set_line_marker(int which, QwtSymbol::Style marker) = 0;
+ virtual void set_line_style(int which, int style) = 0;
+ virtual void set_line_marker(int which, int marker) = 0;
virtual void set_nsamps(const int newsize) = 0;
virtual void set_samp_rate(const double samp_rate) = 0;
+ virtual void set_line_alpha(int which, double alpha) = 0;
+
+ virtual std::string title() = 0;
+ virtual std::string line_label(int which) = 0;
+ virtual std::string line_color(int which) = 0;
+ virtual int line_width(int which) = 0;
+ virtual int line_style(int which) = 0;
+ virtual int line_marker(int which) = 0;
+ virtual double line_alpha(int which) = 0;
virtual void set_size(int width, int height) = 0;
+ virtual void enable_menu(bool en=true) = 0;
+ virtual void enable_grid(bool en=true) = 0;
+ virtual void toggle_stem_plot() = 0;
virtual int nsamps() const = 0;
virtual void reset() = 0;
diff --git a/gr-qtgui/include/qtgui/time_sink_f.h b/gr-qtgui/include/qtgui/time_sink_f.h
index 274896c038..6f689e7b60 100644
--- a/gr-qtgui/include/qtgui/time_sink_f.h
+++ b/gr-qtgui/include/qtgui/time_sink_f.h
@@ -27,7 +27,6 @@
#include <qtgui/api.h>
#include <gr_sync_block.h>
#include <qapplication.h>
-#include <qwt_symbol.h>
namespace gr {
namespace qtgui {
@@ -58,7 +57,7 @@ namespace gr {
*/
static sptr make(int size, double samp_rate,
const std::string &name,
- int nconnections,
+ int nconnections=1,
QWidget *parent=NULL);
virtual void exec_() = 0;
@@ -70,13 +69,25 @@ namespace gr {
virtual void set_line_label(int which, const std::string &line) = 0;
virtual void set_line_color(int which, const std::string &color) = 0;
virtual void set_line_width(int which, int width) = 0;
- virtual void set_line_style(int which, Qt::PenStyle style) = 0;
- virtual void set_line_marker(int which, QwtSymbol::Style marker) = 0;
+ virtual void set_line_style(int which, int style) = 0;
+ virtual void set_line_marker(int which, int marker) = 0;
virtual void set_nsamps(const int newsize) = 0;
virtual void set_samp_rate(const double samp_rate) = 0;
+ virtual void set_line_alpha(int which, double alpha) = 0;
+
+ virtual std::string title() = 0;
+ virtual std::string line_label(int which) = 0;
+ virtual std::string line_color(int which) = 0;
+ virtual int line_width(int which) = 0;
+ virtual int line_style(int which) = 0;
+ virtual int line_marker(int which) = 0;
+ virtual double line_alpha(int which) = 0;
virtual void set_size(int width, int height) = 0;
+ virtual void enable_menu(bool en=true) = 0;
+ virtual void enable_grid(bool en=true) = 0;
+ virtual void toggle_stem_plot() = 0;
virtual int nsamps() const = 0;
virtual void reset() = 0;
diff --git a/gr-qtgui/include/qtgui/waterfall_sink_c.h b/gr-qtgui/include/qtgui/waterfall_sink_c.h
index 93557b6a63..5bc921ccb3 100644
--- a/gr-qtgui/include/qtgui/waterfall_sink_c.h
+++ b/gr-qtgui/include/qtgui/waterfall_sink_c.h
@@ -27,7 +27,7 @@
#include <qtgui/api.h>
#include <gr_sync_block.h>
#include <qapplication.h>
-#include <qwt_symbol.h>
+#include <filter/firdes.h>
namespace gr {
namespace qtgui {
@@ -63,34 +63,52 @@ namespace gr {
* \param fc center frequency of signal (use for x-axis labels)
* \param bw bandwidth of signal (used to set x-axis labels)
* \param name title for the plot
+ * \param nconnections number of signals to be connected to the sink
* \param parent a QWidget parent object, if any
*/
static sptr make(int size, int wintype,
double fc, double bw,
const std::string &name,
+ int nconnections=1,
QWidget *parent=NULL);
virtual void exec_() = 0;
virtual PyObject* pyqwidget() = 0;
+ virtual void clear_data() = 0;
+
virtual void set_fft_size(const int fftsize) = 0;
virtual int fft_size() const = 0;
virtual void set_fft_average(const float fftavg) = 0;
virtual float fft_average() const = 0;
+ virtual void set_fft_window(const gr::filter::firdes::win_type win) = 0;
+ virtual gr::filter::firdes::win_type fft_window() = 0;
virtual void set_frequency_range(const double centerfreq,
const double bandwidth) = 0;
+ virtual void set_intensity_range(const double min,
+ const double max) = 0;
virtual void set_update_time(double t) = 0;
virtual void set_title(const std::string &title) = 0;
- virtual void set_line_label(const std::string &line) = 0;
- virtual void set_line_color(const std::string &color) = 0;
- virtual void set_line_width(int width) = 0;
- virtual void set_line_style(Qt::PenStyle style) = 0;
- virtual void set_line_marker(QwtSymbol::Style marker) = 0;
+ virtual void set_line_label(int which, const std::string &line) = 0;
+ virtual void set_line_alpha(int which, double alpha) = 0;
+ virtual void set_color_map(int which, const int color) = 0;
+
+ virtual std::string title() = 0;
+ virtual std::string line_label(int which) = 0;
+ virtual double line_alpha(int which) = 0;
+ virtual int color_map(int which) = 0;
virtual void set_size(int width, int height) = 0;
+ virtual void auto_scale() = 0;
+ virtual double min_intensity(int which) = 0;
+ virtual double max_intensity(int which) = 0;
+
+ virtual void enable_menu(bool en=true) = 0;
+ virtual void enable_grid(bool en=true) = 0;
+
QApplication *d_qApplication;
};
diff --git a/gr-qtgui/include/qtgui/waterfall_sink_f.h b/gr-qtgui/include/qtgui/waterfall_sink_f.h
index a09ab2852f..98a434e668 100644
--- a/gr-qtgui/include/qtgui/waterfall_sink_f.h
+++ b/gr-qtgui/include/qtgui/waterfall_sink_f.h
@@ -27,7 +27,7 @@
#include <qtgui/api.h>
#include <gr_sync_block.h>
#include <qapplication.h>
-#include <qwt_symbol.h>
+#include <filter/firdes.h>
namespace gr {
namespace qtgui {
@@ -62,34 +62,52 @@ namespace gr {
* \param fc center frequency of signal (use for x-axis labels)
* \param bw bandwidth of signal (used to set x-axis labels)
* \param name title for the plot
+ * \param nconnections number of signals to be connected to the sink
* \param parent a QWidget parent object, if any
*/
static sptr make(int size, int wintype,
double fc, double bw,
const std::string &name,
+ int nconnections=1,
QWidget *parent=NULL);
virtual void exec_() = 0;
virtual PyObject* pyqwidget() = 0;
+ virtual void clear_data() = 0;
+
virtual void set_fft_size(const int fftsize) = 0;
virtual int fft_size() const = 0;
virtual void set_fft_average(const float fftavg) = 0;
virtual float fft_average() const = 0;
+ virtual void set_fft_window(const gr::filter::firdes::win_type win) = 0;
+ virtual gr::filter::firdes::win_type fft_window() = 0;
virtual void set_frequency_range(const double centerfreq,
const double bandwidth) = 0;
+ virtual void set_intensity_range(const double min,
+ const double max) = 0;
virtual void set_update_time(double t) = 0;
virtual void set_title(const std::string &title) = 0;
- virtual void set_line_label(const std::string &line) = 0;
- virtual void set_line_color(const std::string &color) = 0;
- virtual void set_line_width(int width) = 0;
- virtual void set_line_style(Qt::PenStyle style) = 0;
- virtual void set_line_marker(QwtSymbol::Style marker) = 0;
+ virtual void set_line_label(int which, const std::string &line) = 0;
+ virtual void set_line_alpha(int which, double alpha) = 0;
+ virtual void set_color_map(int which, const int color) = 0;
+
+ virtual std::string title() = 0;
+ virtual std::string line_label(int which) = 0;
+ virtual double line_alpha(int which) = 0;
+ virtual int color_map(int which) = 0;
virtual void set_size(int width, int height) = 0;
+ virtual void auto_scale() = 0;
+ virtual double min_intensity(int which) = 0;
+ virtual double max_intensity(int which) = 0;
+
+ virtual void enable_menu(bool en=true) = 0;
+ virtual void enable_grid(bool en=true) = 0;
+
QApplication *d_qApplication;
};
diff --git a/gr-qtgui/lib/DisplayPlot.cc b/gr-qtgui/lib/DisplayPlot.cc
index bf1c198897..f39fbee3ac 100644
--- a/gr-qtgui/lib/DisplayPlot.cc
+++ b/gr-qtgui/lib/DisplayPlot.cc
@@ -113,7 +113,7 @@ DisplayPlot::setLineLabel(int which, QString label)
}
QString
-DisplayPlot::lineLabel(int which)
+DisplayPlot::getLineLabel(int which)
{
return _plot_curve[which]->title().text();
}
diff --git a/gr-qtgui/lib/DisplayPlot.h b/gr-qtgui/lib/DisplayPlot.h
index 26d9412344..0f038a2a28 100644
--- a/gr-qtgui/lib/DisplayPlot.h
+++ b/gr-qtgui/lib/DisplayPlot.h
@@ -179,6 +179,7 @@ public slots:
void setYaxis(double min, double max);
void setXaxis(double min, double max);
void setLineLabel(int which, QString label);
+ QString getLineLabel(int which);
void setLineColor(int which, QColor color);
QColor getLineColor(int which) const;
void setLineWidth(int which, int width);
@@ -250,8 +251,6 @@ public slots:
void setStop(bool on);
- QString lineLabel(int which);
-
void resizeSlot(QSize *s);
// Because of the preprocessing of slots in QT, these are not
diff --git a/gr-qtgui/lib/FrequencyDisplayPlot.cc b/gr-qtgui/lib/FrequencyDisplayPlot.cc
index 52ff335c32..1ed0911686 100644
--- a/gr-qtgui/lib/FrequencyDisplayPlot.cc
+++ b/gr-qtgui/lib/FrequencyDisplayPlot.cc
@@ -107,10 +107,16 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(int nplots, QWidget* parent)
_plot_curve.push_back(new QwtPlotCurve(QString("Data %1").arg(i)));
_plot_curve[i]->attach(this);
+
+ QwtSymbol *symbol = new QwtSymbol(QwtSymbol::NoSymbol, QBrush(default_colors[i]),
+ QPen(default_colors[i]), QSize(7,7));
+
#if QWT_VERSION < 0x060000
_plot_curve[i]->setRawData(_xAxisPoints, _dataPoints[i], _numPoints);
+ _plot_curve[i]->setSymbol(*symbol);
#else
_plot_curve[i]->setRawSamples(_xAxisPoints, _dataPoints[i], _numPoints);
+ _plot_curve[i]->setSymbol(symbol);
#endif
setLineColor(i, default_colors[i]);
}
diff --git a/gr-qtgui/lib/TimeDomainDisplayPlot.cc b/gr-qtgui/lib/TimeDomainDisplayPlot.cc
index f3c3b4deb3..1f63b43abd 100644
--- a/gr-qtgui/lib/TimeDomainDisplayPlot.cc
+++ b/gr-qtgui/lib/TimeDomainDisplayPlot.cc
@@ -249,4 +249,22 @@ TimeDomainDisplayPlot::setSampleRate(double sr, double units,
}
}
+void
+TimeDomainDisplayPlot::stemPlot(bool trig)
+{
+ if(trig) {
+ for(int i = 0; i < _nplots; i++) {
+ _plot_curve[i]->setStyle(QwtPlotCurve::Sticks);
+ setLineMarker(i, QwtSymbol::Ellipse);
+ }
+ }
+ else {
+ for(int i = 0; i < _nplots; i++) {
+ _plot_curve[i]->setStyle(QwtPlotCurve::Lines);
+ setLineMarker(i, QwtSymbol::NoSymbol);
+ }
+ }
+ replot();
+}
+
#endif /* TIME_DOMAIN_DISPLAY_PLOT_C */
diff --git a/gr-qtgui/lib/TimeDomainDisplayPlot.h b/gr-qtgui/lib/TimeDomainDisplayPlot.h
index c7d5f27a5d..e4bbf0500a 100644
--- a/gr-qtgui/lib/TimeDomainDisplayPlot.h
+++ b/gr-qtgui/lib/TimeDomainDisplayPlot.h
@@ -41,6 +41,8 @@ public:
void replot();
+ void stemPlot(bool trig);
+
public slots:
void setSampleRate(double sr, double units,
const std::string &strunits);
diff --git a/gr-qtgui/lib/WaterfallDisplayPlot.cc b/gr-qtgui/lib/WaterfallDisplayPlot.cc
index be0cfc18a3..05c89e3ecb 100644
--- a/gr-qtgui/lib/WaterfallDisplayPlot.cc
+++ b/gr-qtgui/lib/WaterfallDisplayPlot.cc
@@ -40,22 +40,6 @@ namespace pt = boost::posix_time;
#include <QDebug>
/***********************************************************************
- * Create a time label HH:MM:SS.SSS from an input time
- **********************************************************************/
-static QString
-make_time_label(double secs)
-{
- std::string time_str = pt::to_simple_string(pt::from_time_t(time_t(secs)));
-
- // lops off the YYYY-mmm-DD part of the string
- size_t ind = time_str.find(" ");
- if(ind != std::string::npos)
- time_str = time_str.substr(ind);
-
- return QString("").sprintf("%s.%03ld", time_str.c_str(), long(std::fmod(secs*1000, 1000)));
-}
-
-/***********************************************************************
* Text scale widget to provide Y (time) axis text
**********************************************************************/
class QwtTimeScaleDraw: public QwtScaleDraw, public TimeScaleData
@@ -154,13 +138,6 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(int nplots, QWidget* parent)
_lastReplot = 0;
- QList<int> colormaps;
- colormaps << INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR
- << INTENSITY_COLOR_MAP_TYPE_WHITE_HOT
- << INTENSITY_COLOR_MAP_TYPE_BLACK_HOT
- << INTENSITY_COLOR_MAP_TYPE_INCANDESCENT
- << INTENSITY_COLOR_MAP_TYPE_USER_DEFINED;
-
for(int i = 0; i < _nplots; i++) {
d_data.push_back(new WaterfallData(_startFrequency, _stopFrequency,
_numPoints, 200));
@@ -181,11 +158,16 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(int nplots, QWidget* parent)
d_spectrogram[i]->attach(this);
- _intensityColorMapType.push_back(colormaps[i%colormaps.size()]);
+ _intensityColorMapType.push_back(INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR);
setIntensityColorMapType(i, _intensityColorMapType[i],
QColor("white"), QColor("white"));
+
+ setAlpha(i, 255/_nplots);
}
+ // Set bottom plot with no transparency as a base
+ setAlpha(0, 255);
+
// LeftButton for the zooming
// MidButton for the panning
// RightButton: zoom out by 1
@@ -357,6 +339,30 @@ WaterfallDisplayPlot::setIntensityRange(const double minIntensity,
}
}
+double
+WaterfallDisplayPlot::getMinIntensity(int which) const
+{
+#if QWT_VERSION < 0x060000
+ QwtDoubleInterval r = d_data[which]->range();
+#else
+ QwtInterval r = d_data[which]->interval(Qt::ZAxis);
+#endif
+
+ return r.minValue();
+}
+
+double
+WaterfallDisplayPlot::getMaxIntensity(int which) const
+{
+#if QWT_VERSION < 0x060000
+ QwtDoubleInterval r = d_data[which]->range();
+#else
+ QwtInterval r = d_data[which]->interval(Qt::ZAxis);
+#endif
+
+ return r.maxValue();
+}
+
void
WaterfallDisplayPlot::replot()
{
@@ -384,6 +390,15 @@ WaterfallDisplayPlot::replot()
QwtPlot::replot();
}
+void
+WaterfallDisplayPlot::clearData()
+{
+ for(int i = 0; i < _nplots; i++) {
+ d_data[i]->reset();
+ }
+}
+
+
int
WaterfallDisplayPlot::getIntensityColorMapType(int which) const
{
@@ -495,6 +510,18 @@ WaterfallDisplayPlot::getUserDefinedHighIntensityColor() const
return _userDefinedHighIntensityColor;
}
+int
+WaterfallDisplayPlot::getAlpha(int which)
+{
+ return d_spectrogram[which]->alpha();
+}
+
+void
+WaterfallDisplayPlot::setAlpha(int which, int alpha)
+{
+ d_spectrogram[which]->setAlpha(alpha);
+}
+
void
WaterfallDisplayPlot::_updateIntensityRangeDisplay()
{
diff --git a/gr-qtgui/lib/WaterfallDisplayPlot.h b/gr-qtgui/lib/WaterfallDisplayPlot.h
index e962a6c881..6637adc594 100644
--- a/gr-qtgui/lib/WaterfallDisplayPlot.h
+++ b/gr-qtgui/lib/WaterfallDisplayPlot.h
@@ -72,14 +72,20 @@ public:
const int droppedFrames);
void setIntensityRange(const double minIntensity, const double maxIntensity);
+ double getMinIntensity(int which) const;
+ double getMaxIntensity(int which) const;
void replot(void);
+ void clearData();
int getIntensityColorMapType(int) const;
int getIntensityColorMapType1() const;
const QColor getUserDefinedLowIntensityColor() const;
const QColor getUserDefinedHighIntensityColor() const;
+ int getAlpha(int which);
+ void setAlpha(int which, int alpha);
+
public slots:
void setIntensityColorMapType(const int, const int, const QColor, const QColor);
void setIntensityColorMapType1(int);
diff --git a/gr-qtgui/lib/const_sink_c_impl.cc b/gr-qtgui/lib/const_sink_c_impl.cc
index 808312e8a7..2490e9a618 100644
--- a/gr-qtgui/lib/const_sink_c_impl.cc
+++ b/gr-qtgui/lib/const_sink_c_impl.cc
@@ -29,6 +29,7 @@
#include <string.h>
#include <volk/volk.h>
#include <fft/fft.h>
+#include <qwt_symbol.h>
namespace gr {
namespace qtgui {
@@ -172,15 +173,21 @@ namespace gr {
}
void
- const_sink_c_impl::set_line_style(int which, Qt::PenStyle style)
+ const_sink_c_impl::set_line_style(int which, int style)
{
- d_main_gui->setLineStyle(which, style);
+ d_main_gui->setLineStyle(which, (Qt::PenStyle)style);
}
void
- const_sink_c_impl::set_line_marker(int which, QwtSymbol::Style marker)
+ const_sink_c_impl::set_line_marker(int which, int marker)
{
- d_main_gui->setLineMarker(which, marker);
+ d_main_gui->setLineMarker(which, (QwtSymbol::Style)marker);
+ }
+
+ void
+ const_sink_c_impl::set_line_alpha(int which, double alpha)
+ {
+ d_main_gui->setMarkerAlpha(which, (int)(255.0*alpha));
}
void
@@ -189,6 +196,48 @@ namespace gr {
d_main_gui->resize(QSize(width, height));
}
+ std::string
+ const_sink_c_impl::title()
+ {
+ return d_main_gui->title().toStdString();
+ }
+
+ std::string
+ const_sink_c_impl::line_label(int which)
+ {
+ return d_main_gui->lineLabel(which).toStdString();
+ }
+
+ std::string
+ const_sink_c_impl::line_color(int which)
+ {
+ return d_main_gui->lineColor(which).toStdString();
+ }
+
+ int
+ const_sink_c_impl::line_width(int which)
+ {
+ return d_main_gui->lineWidth(which);
+ }
+
+ int
+ const_sink_c_impl::line_style(int which)
+ {
+ return d_main_gui->lineStyle(which);
+ }
+
+ int
+ const_sink_c_impl::line_marker(int which)
+ {
+ return d_main_gui->lineMarker(which);
+ }
+
+ double
+ const_sink_c_impl::line_alpha(int which)
+ {
+ return (double)(d_main_gui->markerAlpha(which))/255.0;
+ }
+
void
const_sink_c_impl::set_nsamps(const int newsize)
{
@@ -229,6 +278,12 @@ namespace gr {
}
void
+ const_sink_c_impl::enable_menu(bool en)
+ {
+ d_main_gui->enableMenu(en);
+ }
+
+ void
const_sink_c_impl::reset()
{
d_index = 0;
diff --git a/gr-qtgui/lib/const_sink_c_impl.h b/gr-qtgui/lib/const_sink_c_impl.h
index 9e943b9a68..3e90d00429 100644
--- a/gr-qtgui/lib/const_sink_c_impl.h
+++ b/gr-qtgui/lib/const_sink_c_impl.h
@@ -75,13 +75,23 @@ namespace gr {
void set_line_label(int which, const std::string &label);
void set_line_color(int which, const std::string &color);
void set_line_width(int which, int width);
- void set_line_style(int which, Qt::PenStyle style);
- void set_line_marker(int which, QwtSymbol::Style marker);
+ void set_line_style(int which, int style);
+ void set_line_marker(int which, int marker);
void set_nsamps(const int size);
+ void set_line_alpha(int which, double alpha);
+
+ std::string title();
+ std::string line_label(int which);
+ std::string line_color(int which);
+ int line_width(int which);
+ int line_style(int which);
+ int line_marker(int which);
+ double line_alpha(int which);
void set_size(int width, int height);
int nsamps() const;
+ void enable_menu(bool en);
void reset();
int work(int noutput_items,
diff --git a/gr-qtgui/lib/displayform.cc b/gr-qtgui/lib/displayform.cc
index e2475cb95e..40cd8e9742 100644
--- a/gr-qtgui/lib/displayform.cc
+++ b/gr-qtgui/lib/displayform.cc
@@ -47,6 +47,7 @@ DisplayForm::DisplayForm(int nplots, QWidget* parent)
_grid_state = false;
// Create a pop-up menu for manipulating the figure
+ _menu_on = true;
_menu = new QMenu(this);
_menu->addAction(_stop_act);
_menu->addAction(_grid_act);
@@ -130,7 +131,7 @@ DisplayForm::resizeEvent( QResizeEvent *e )
void
DisplayForm::mousePressEvent( QMouseEvent * e)
{
- if(e->button() == Qt::RightButton) {
+ if((e->button() == Qt::RightButton) && (_menu_on)) {
QwtPlotLayout *plt = _displayPlot->plotLayout();
QRectF cvs = plt->canvasRect();
@@ -153,7 +154,7 @@ DisplayForm::mousePressEvent( QMouseEvent * e)
// Update the line titles if changed externally
for(int i = 0; i < _nplots; i++) {
- _lines_menu[i]->setTitle(_displayPlot->lineLabel(i));
+ _lines_menu[i]->setTitle(_displayPlot->getLineLabel(i));
}
_menu->exec(e->globalPos());
}
@@ -177,6 +178,11 @@ DisplayForm::Reset()
{
}
+void
+DisplayForm::enableMenu(bool en)
+{
+ _menu_on = en;
+}
void
DisplayForm::closeEvent( QCloseEvent *e )
@@ -240,6 +246,48 @@ DisplayForm::setMarkerAlpha(int which, int alpha)
_displayPlot->replot();
}
+QString
+DisplayForm::title()
+{
+ return _displayPlot->title().text();
+}
+
+QString
+DisplayForm::lineLabel(int which)
+{
+ return _displayPlot->getLineLabel(which);
+}
+
+QString
+DisplayForm::lineColor(int which)
+{
+ return _displayPlot->getLineColor(which).name();
+}
+
+int
+DisplayForm::lineWidth(int which)
+{
+ return _displayPlot->getLineWidth(which);
+}
+
+Qt::PenStyle
+DisplayForm::lineStyle(int which)
+{
+ return _displayPlot->getLineStyle(which);
+}
+
+QwtSymbol::Style
+DisplayForm::lineMarker(int which)
+{
+ return _displayPlot->getLineMarker(which);
+}
+
+int
+DisplayForm::markerAlpha(int which)
+{
+ return _displayPlot->getMarkerAlpha(which);
+}
+
void
DisplayForm::setStop(bool on)
{
diff --git a/gr-qtgui/lib/displayform.h b/gr-qtgui/lib/displayform.h
index 99b0e714f4..542ad51d9d 100644
--- a/gr-qtgui/lib/displayform.h
+++ b/gr-qtgui/lib/displayform.h
@@ -44,6 +44,8 @@ class DisplayForm : public QWidget
virtual DisplayPlot* getPlot() = 0;
void Reset();
+ void enableMenu(bool en=true);
+
public slots:
void resizeEvent( QResizeEvent * e );
void mousePressEvent( QMouseEvent * e);
@@ -61,6 +63,14 @@ public slots:
void setLineMarker(int which, QwtSymbol::Style style);
void setMarkerAlpha(int which, int alpha);
+ QString title();
+ QString lineLabel(int which);
+ QString lineColor(int which);
+ int lineWidth(int which);
+ Qt::PenStyle lineStyle(int which);
+ QwtSymbol::Style lineMarker(int which);
+ int markerAlpha(int which);
+
void setStop(bool on);
void setStop();
@@ -87,6 +97,7 @@ protected:
QwtPlotGrid *_grid;
+ bool _menu_on;
QMenu *_menu;
QAction *_stop_act;
diff --git a/gr-qtgui/lib/form_menus.h b/gr-qtgui/lib/form_menus.h
index c84ecbfb44..63ab35ed95 100644
--- a/gr-qtgui/lib/form_menus.h
+++ b/gr-qtgui/lib/form_menus.h
@@ -359,11 +359,13 @@ public:
d_act.push_back(new QAction("Low", this));
d_act.push_back(new QAction("Medium", this));
d_act.push_back(new QAction("High", this));
+ d_act.push_back(new QAction("Off", this));
connect(d_act[0], SIGNAL(triggered()), this, SLOT(getNone()));
connect(d_act[1], SIGNAL(triggered()), this, SLOT(getLow()));
connect(d_act[2], SIGNAL(triggered()), this, SLOT(getMedium()));
connect(d_act[3], SIGNAL(triggered()), this, SLOT(getHigh()));
+ connect(d_act[4], SIGNAL(triggered()), this, SLOT(getOff()));
QListIterator<QAction*> i(d_act);
while(i.hasNext()) {
@@ -396,6 +398,7 @@ public slots:
void getLow() { emit whichTrigger(d_which, 200); }
void getMedium() { emit whichTrigger(d_which, 125); }
void getHigh() { emit whichTrigger(d_which, 50); }
+ void getOff() { emit whichTrigger(d_which, 0); }
private:
QList<QAction *> d_act;
@@ -864,8 +867,8 @@ class ColorMapMenu: public QMenu
Q_OBJECT
public:
- ColorMapMenu(QWidget *parent)
- : QMenu("Color Map", parent)
+ ColorMapMenu(int which, QWidget *parent)
+ : QMenu("Color Map", parent), d_which(which)
{
d_act.push_back(new QAction("Multi-Color", this));
d_act.push_back(new QAction("White Hot", this));
@@ -907,15 +910,16 @@ public:
}
signals:
- void whichTrigger(const int type, const QColor &min_color=QColor(),
+ void whichTrigger(int which, const int type,
+ const QColor &min_color=QColor(),
const QColor &max_color=QColor());
public slots:
- void getMultiColor() { emit whichTrigger(INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR); }
- void getWhiteHot() { emit whichTrigger(INTENSITY_COLOR_MAP_TYPE_WHITE_HOT); }
- void getBlackHot() { emit whichTrigger(INTENSITY_COLOR_MAP_TYPE_BLACK_HOT); }
- void getIncandescent() { emit whichTrigger(INTENSITY_COLOR_MAP_TYPE_INCANDESCENT); }
- //void getOther(const QString &min_str, const QString &max_str)
+ void getMultiColor() { emit whichTrigger(d_which, INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR); }
+ void getWhiteHot() { emit whichTrigger(d_which, INTENSITY_COLOR_MAP_TYPE_WHITE_HOT); }
+ void getBlackHot() { emit whichTrigger(d_which, INTENSITY_COLOR_MAP_TYPE_BLACK_HOT); }
+ void getIncandescent() { emit whichTrigger(d_which, INTENSITY_COLOR_MAP_TYPE_INCANDESCENT); }
+ //void getOther(d_which, const QString &min_str, const QString &max_str)
void getOther()
{
QMessageBox::information(this, "Set low and high intensities",
@@ -924,7 +928,7 @@ public:
d_min_value = QColorDialog::getColor(d_min_value, this);
d_max_value = QColorDialog::getColor(d_max_value, this);
- emit whichTrigger(INTENSITY_COLOR_MAP_TYPE_USER_DEFINED,
+ emit whichTrigger(d_which, INTENSITY_COLOR_MAP_TYPE_USER_DEFINED,
d_min_value, d_max_value);
}
@@ -932,6 +936,62 @@ private:
QList<QAction *> d_act;
OtherDualAction *d_other;
QColor d_max_value, d_min_value;
+ int d_which;
+};
+
+
+/********************************************************************/
+
+
+class PopupMenu: public QAction
+{
+ Q_OBJECT
+
+public:
+ PopupMenu(QString desc, QWidget *parent)
+ : QAction(desc, parent)
+ {
+ d_diag = new QDialog(parent);
+ d_diag->setModal(true);
+
+ d_text = new QLineEdit();
+
+ QGridLayout *layout = new QGridLayout(d_diag);
+ QPushButton *btn_ok = new QPushButton(tr("OK"));
+ QPushButton *btn_cancel = new QPushButton(tr("Cancel"));
+
+ layout->addWidget(d_text, 0, 0, 1, 2);
+ layout->addWidget(btn_ok, 1, 0);
+ layout->addWidget(btn_cancel, 1, 1);
+
+ connect(btn_ok, SIGNAL(clicked()), this, SLOT(getText()));
+ connect(btn_cancel, SIGNAL(clicked()), d_diag, SLOT(close()));
+
+ connect(this, SIGNAL(triggered()), this, SLOT(getTextDiag()));
+ }
+
+ ~PopupMenu()
+ {}
+
+signals:
+ void whichTrigger(const QString data);
+
+public slots:
+ void getTextDiag()
+ {
+ d_diag->show();
+ }
+
+private slots:
+ void getText()
+ {
+ emit whichTrigger(d_text->text());
+ d_diag->accept();
+ }
+
+private:
+ QDialog *d_diag;
+ QLineEdit *d_text;
};
diff --git a/gr-qtgui/lib/freq_sink_c_impl.cc b/gr-qtgui/lib/freq_sink_c_impl.cc
index 2db5cf56bb..78d7431b20 100644
--- a/gr-qtgui/lib/freq_sink_c_impl.cc
+++ b/gr-qtgui/lib/freq_sink_c_impl.cc
@@ -28,6 +28,7 @@
#include <gr_io_signature.h>
#include <string.h>
#include <volk/volk.h>
+#include <qwt_symbol.h>
namespace gr {
namespace qtgui {
@@ -121,8 +122,7 @@ namespace gr {
}
d_main_gui = new FreqDisplayForm(d_nconnections, d_parent);
- d_main_gui->setFFTWindowType(d_wintype);
-
+ set_fft_window(d_wintype);
set_fft_size(d_fftsize);
set_frequency_range(d_center_freq, d_bandwidth);
@@ -154,7 +154,6 @@ namespace gr {
void
freq_sink_c_impl::set_fft_size(const int fftsize)
{
- d_fftsize = fftsize;
d_main_gui->setFFTSize(fftsize);
}
@@ -167,7 +166,6 @@ namespace gr {
void
freq_sink_c_impl::set_fft_average(const float fftavg)
{
- d_fftavg = fftavg;
d_main_gui->setFFTAverage(fftavg);
}
@@ -178,6 +176,18 @@ namespace gr {
}
void
+ freq_sink_c_impl::set_fft_window(const filter::firdes::win_type win)
+ {
+ d_main_gui->setFFTWindowType(win);
+ }
+
+ filter::firdes::win_type
+ freq_sink_c_impl::fft_window()
+ {
+ return d_wintype;
+ }
+
+ void
freq_sink_c_impl::set_frequency_range(const double centerfreq,
const double bandwidth)
{
@@ -226,15 +236,21 @@ namespace gr {
}
void
- freq_sink_c_impl::set_line_style(int which, Qt::PenStyle style)
+ freq_sink_c_impl::set_line_style(int which, int style)
+ {
+ d_main_gui->setLineStyle(which, (Qt::PenStyle)style);
+ }
+
+ void
+ freq_sink_c_impl::set_line_marker(int which, int marker)
{
- d_main_gui->setLineStyle(which, style);
+ d_main_gui->setLineMarker(which, (QwtSymbol::Style)marker);
}
void
- freq_sink_c_impl::set_line_marker(int which, QwtSymbol::Style marker)
+ freq_sink_c_impl::set_line_alpha(int which, double alpha)
{
- d_main_gui->setLineMarker(which, marker);
+ d_main_gui->setMarkerAlpha(which, (int)(255.0*alpha));
}
void
@@ -243,6 +259,60 @@ namespace gr {
d_main_gui->resize(QSize(width, height));
}
+ std::string
+ freq_sink_c_impl::title()
+ {
+ return d_main_gui->title().toStdString();
+ }
+
+ std::string
+ freq_sink_c_impl::line_label(int which)
+ {
+ return d_main_gui->lineLabel(which).toStdString();
+ }
+
+ std::string
+ freq_sink_c_impl::line_color(int which)
+ {
+ return d_main_gui->lineColor(which).toStdString();
+ }
+
+ int
+ freq_sink_c_impl::line_width(int which)
+ {
+ return d_main_gui->lineWidth(which);
+ }
+
+ int
+ freq_sink_c_impl::line_style(int which)
+ {
+ return d_main_gui->lineStyle(which);
+ }
+
+ int
+ freq_sink_c_impl::line_marker(int which)
+ {
+ return d_main_gui->lineMarker(which);
+ }
+
+ double
+ freq_sink_c_impl::line_alpha(int which)
+ {
+ return (double)(d_main_gui->markerAlpha(which))/255.0;
+ }
+
+ void
+ freq_sink_c_impl::enable_menu(bool en)
+ {
+ d_main_gui->enableMenu(en);
+ }
+
+ void
+ freq_sink_c_impl::enable_grid(bool en)
+ {
+ d_main_gui->setGrid(en);
+ }
+
void
freq_sink_c_impl::reset()
{
diff --git a/gr-qtgui/lib/freq_sink_c_impl.h b/gr-qtgui/lib/freq_sink_c_impl.h
index 4bcf93b372..77a625eb13 100644
--- a/gr-qtgui/lib/freq_sink_c_impl.h
+++ b/gr-qtgui/lib/freq_sink_c_impl.h
@@ -88,20 +88,34 @@ namespace gr {
int fft_size() const;
void set_fft_average(const float fftavg);
float fft_average() const;
+ void set_fft_window(const filter::firdes::win_type win);
+ filter::firdes::win_type fft_window();
void set_frequency_range(const double centerfreq, const double bandwidth);
void set_y_axis(double min, double max);
void set_update_time(double t);
+
void set_title(const std::string &title);
void set_line_label(int which, const std::string &label);
void set_line_color(int which, const std::string &color);
void set_line_width(int which, int width);
- void set_line_style(int which, Qt::PenStyle style);
- void set_line_marker(int which, QwtSymbol::Style marker);
+ void set_line_style(int which, int style);
+ void set_line_marker(int which, int marker);
+ void set_line_alpha(int which, double alpha);
+
+ std::string title();
+ std::string line_label(int which);
+ std::string line_color(int which);
+ int line_width(int which);
+ int line_style(int which);
+ int line_marker(int which);
+ double line_alpha(int which);
void set_size(int width, int height);
+ void enable_menu(bool en);
+ void enable_grid(bool en);
void reset();
int work(int noutput_items,
diff --git a/gr-qtgui/lib/freq_sink_f_impl.cc b/gr-qtgui/lib/freq_sink_f_impl.cc
index c0edf415a5..457235df6f 100644
--- a/gr-qtgui/lib/freq_sink_f_impl.cc
+++ b/gr-qtgui/lib/freq_sink_f_impl.cc
@@ -28,6 +28,7 @@
#include <gr_io_signature.h>
#include <string.h>
#include <volk/volk.h>
+#include <qwt_symbol.h>
namespace gr {
namespace qtgui {
@@ -121,7 +122,7 @@ namespace gr {
}
d_main_gui = new FreqDisplayForm(d_nconnections, d_parent);
- d_main_gui->setFFTWindowType(d_wintype);
+ set_fft_window(d_wintype);
set_fft_size(d_fftsize);
set_frequency_range(d_center_freq, d_bandwidth/2.0);
@@ -153,7 +154,6 @@ namespace gr {
void
freq_sink_f_impl::set_fft_size(const int fftsize)
{
- d_fftsize = fftsize;
d_main_gui->setFFTSize(fftsize);
}
@@ -166,7 +166,6 @@ namespace gr {
void
freq_sink_f_impl::set_fft_average(const float fftavg)
{
- d_fftavg = fftavg;
d_main_gui->setFFTAverage(fftavg);
}
@@ -177,6 +176,18 @@ namespace gr {
}
void
+ freq_sink_f_impl::set_fft_window(const filter::firdes::win_type win)
+ {
+ d_main_gui->setFFTWindowType(win);
+ }
+
+ filter::firdes::win_type
+ freq_sink_f_impl::fft_window()
+ {
+ return d_wintype;
+ }
+
+ void
freq_sink_f_impl::set_frequency_range(const double centerfreq,
const double bandwidth)
{
@@ -225,17 +236,22 @@ namespace gr {
}
void
- freq_sink_f_impl::set_line_style(int which, Qt::PenStyle style)
+ freq_sink_f_impl::set_line_style(int which, int style)
{
- d_main_gui->setLineStyle(which, style);
+ d_main_gui->setLineStyle(which, (Qt::PenStyle)style);
}
void
- freq_sink_f_impl::set_line_marker(int which, QwtSymbol::Style marker)
+ freq_sink_f_impl::set_line_marker(int which, int marker)
{
- d_main_gui->setLineMarker(which, marker);
+ d_main_gui->setLineMarker(which, (QwtSymbol::Style)marker);
}
+ void
+ freq_sink_f_impl::set_line_alpha(int which, double alpha)
+ {
+ d_main_gui->setMarkerAlpha(which, (int)(255.0*alpha));
+ }
void
freq_sink_f_impl::set_size(int width, int height)
@@ -243,6 +259,60 @@ namespace gr {
d_main_gui->resize(QSize(width, height));
}
+ std::string
+ freq_sink_f_impl::title()
+ {
+ return d_main_gui->title().toStdString();
+ }
+
+ std::string
+ freq_sink_f_impl::line_label(int which)
+ {
+ return d_main_gui->lineLabel(which).toStdString();
+ }
+
+ std::string
+ freq_sink_f_impl::line_color(int which)
+ {
+ return d_main_gui->lineColor(which).toStdString();
+ }
+
+ int
+ freq_sink_f_impl::line_width(int which)
+ {
+ return d_main_gui->lineWidth(which);
+ }
+
+ int
+ freq_sink_f_impl::line_style(int which)
+ {
+ return d_main_gui->lineStyle(which);
+ }
+
+ int
+ freq_sink_f_impl::line_marker(int which)
+ {
+ return d_main_gui->lineMarker(which);
+ }
+
+ double
+ freq_sink_f_impl::line_alpha(int which)
+ {
+ return (double)(d_main_gui->markerAlpha(which))/255.0;
+ }
+
+ void
+ freq_sink_f_impl::enable_menu(bool en)
+ {
+ d_main_gui->enableMenu(en);
+ }
+
+ void
+ freq_sink_f_impl::enable_grid(bool en)
+ {
+ d_main_gui->setGrid(en);
+ }
+
void
freq_sink_f_impl::reset()
{
diff --git a/gr-qtgui/lib/freq_sink_f_impl.h b/gr-qtgui/lib/freq_sink_f_impl.h
index 8e3fbf1edc..d0a6b2c14b 100644
--- a/gr-qtgui/lib/freq_sink_f_impl.h
+++ b/gr-qtgui/lib/freq_sink_f_impl.h
@@ -88,6 +88,8 @@ namespace gr {
int fft_size() const;
void set_fft_average(const float fftavg);
float fft_average() const;
+ void set_fft_window(const filter::firdes::win_type win);
+ filter::firdes::win_type fft_window();
void set_frequency_range(const double centerfreq, const double bandwidth);
void set_y_axis(double min, double max);
@@ -97,11 +99,22 @@ namespace gr {
void set_line_label(int which, const std::string &label);
void set_line_color(int which, const std::string &color);
void set_line_width(int which, int width);
- void set_line_style(int which, Qt::PenStyle style);
- void set_line_marker(int which, QwtSymbol::Style marker);
+ void set_line_style(int which, int style);
+ void set_line_marker(int which, int marker);
+ void set_line_alpha(int which, double alpha);
+
+ std::string title();
+ std::string line_label(int which);
+ std::string line_color(int which);
+ int line_width(int which);
+ int line_style(int which);
+ int line_marker(int which);
+ double line_alpha(int which);
void set_size(int width, int height);
+ void enable_menu(bool en);
+ void enable_grid(bool en);
void reset();
int work(int noutput_items,
diff --git a/gr-qtgui/lib/freqdisplayform.cc b/gr-qtgui/lib/freqdisplayform.cc
index 4163acc826..938c9cc550 100644
--- a/gr-qtgui/lib/freqdisplayform.cc
+++ b/gr-qtgui/lib/freqdisplayform.cc
@@ -114,6 +114,7 @@ void
FreqDisplayForm::setFFTSize(const int newsize)
{
_fftsize = newsize;
+ getPlot()->replot();
}
void
@@ -127,6 +128,7 @@ void
FreqDisplayForm::setFFTWindowType(const gr::filter::firdes::win_type newwin)
{
_fftwintype = newwin;
+ getPlot()->replot();
}
void
diff --git a/gr-qtgui/lib/time_sink_c_impl.cc b/gr-qtgui/lib/time_sink_c_impl.cc
index 497aeb512d..46db6315eb 100644
--- a/gr-qtgui/lib/time_sink_c_impl.cc
+++ b/gr-qtgui/lib/time_sink_c_impl.cc
@@ -29,6 +29,7 @@
#include <string.h>
#include <volk/volk.h>
#include <fft/fft.h>
+#include <qwt_symbol.h>
namespace gr {
namespace qtgui {
@@ -165,15 +166,21 @@ namespace gr {
}
void
- time_sink_c_impl::set_line_style(int which, Qt::PenStyle style)
+ time_sink_c_impl::set_line_style(int which, int style)
{
- d_main_gui->setLineStyle(which, style);
+ d_main_gui->setLineStyle(which, (Qt::PenStyle)style);
}
void
- time_sink_c_impl::set_line_marker(int which, QwtSymbol::Style marker)
+ time_sink_c_impl::set_line_marker(int which, int marker)
{
- d_main_gui->setLineMarker(which, marker);
+ d_main_gui->setLineMarker(which, (QwtSymbol::Style)marker);
+ }
+
+ void
+ time_sink_c_impl::set_line_alpha(int which, double alpha)
+ {
+ d_main_gui->setMarkerAlpha(which, (int)(255.0*alpha));
}
void
@@ -182,6 +189,48 @@ namespace gr {
d_main_gui->resize(QSize(width, height));
}
+ std::string
+ time_sink_c_impl::title()
+ {
+ return d_main_gui->title().toStdString();
+ }
+
+ std::string
+ time_sink_c_impl::line_label(int which)
+ {
+ return d_main_gui->lineLabel(which).toStdString();
+ }
+
+ std::string
+ time_sink_c_impl::line_color(int which)
+ {
+ return d_main_gui->lineColor(which).toStdString();
+ }
+
+ int
+ time_sink_c_impl::line_width(int which)
+ {
+ return d_main_gui->lineWidth(which);
+ }
+
+ int
+ time_sink_c_impl::line_style(int which)
+ {
+ return d_main_gui->lineStyle(which);
+ }
+
+ int
+ time_sink_c_impl::line_marker(int which)
+ {
+ return d_main_gui->lineMarker(which);
+ }
+
+ double
+ time_sink_c_impl::line_alpha(int which)
+ {
+ return (double)(d_main_gui->markerAlpha(which))/255.0;
+ }
+
void
time_sink_c_impl::set_nsamps(const int newsize)
{
@@ -227,6 +276,24 @@ namespace gr {
}
void
+ time_sink_c_impl::enable_menu(bool en)
+ {
+ d_main_gui->enableMenu(en);
+ }
+
+ void
+ time_sink_c_impl::enable_grid(bool en)
+ {
+ d_main_gui->setGrid(en);
+ }
+
+ void
+ time_sink_c_impl::toggle_stem_plot()
+ {
+ d_main_gui->setStem();
+ }
+
+ void
time_sink_c_impl::reset()
{
d_index = 0;
diff --git a/gr-qtgui/lib/time_sink_c_impl.h b/gr-qtgui/lib/time_sink_c_impl.h
index e728351246..bccb7b1197 100644
--- a/gr-qtgui/lib/time_sink_c_impl.h
+++ b/gr-qtgui/lib/time_sink_c_impl.h
@@ -73,15 +73,27 @@ namespace gr {
void set_line_label(int which, const std::string &label);
void set_line_color(int which, const std::string &color);
void set_line_width(int which, int width);
- void set_line_style(int which, Qt::PenStyle style);
- void set_line_marker(int which, QwtSymbol::Style marker);
+ void set_line_style(int which, int style);
+ void set_line_marker(int which, int marker);
void set_nsamps(const int size);
void set_samp_rate(const double samp_rate);
+ void set_line_alpha(int which, double alpha);
- void set_size(int width, int height);
+ std::string title();
+ std::string line_label(int which);
+ std::string line_color(int which);
+ int line_width(int which);
+ int line_style(int which);
+ int line_marker(int which);
+ double line_alpha(int which);
+ void set_size(int width, int height);
+
int nsamps() const;
+ void enable_menu(bool en);
+ void enable_grid(bool en);
+ void toggle_stem_plot();
void reset();
int work(int noutput_items,
diff --git a/gr-qtgui/lib/time_sink_f_impl.cc b/gr-qtgui/lib/time_sink_f_impl.cc
index 61705218ff..06854c71e7 100644
--- a/gr-qtgui/lib/time_sink_f_impl.cc
+++ b/gr-qtgui/lib/time_sink_f_impl.cc
@@ -29,6 +29,7 @@
#include <string.h>
#include <volk/volk.h>
#include <fft/fft.h>
+#include <qwt_symbol.h>
namespace gr {
namespace qtgui {
@@ -165,15 +166,21 @@ namespace gr {
}
void
- time_sink_f_impl::set_line_style(int which, Qt::PenStyle style)
+ time_sink_f_impl::set_line_style(int which, int style)
{
- d_main_gui->setLineStyle(which, style);
+ d_main_gui->setLineStyle(which, (Qt::PenStyle)style);
}
void
- time_sink_f_impl::set_line_marker(int which, QwtSymbol::Style marker)
+ time_sink_f_impl::set_line_marker(int which, int marker)
{
- d_main_gui->setLineMarker(which, marker);
+ d_main_gui->setLineMarker(which, (QwtSymbol::Style)marker);
+ }
+
+ void
+ time_sink_f_impl::set_line_alpha(int which, double alpha)
+ {
+ d_main_gui->setMarkerAlpha(which, (int)(255.0*alpha));
}
void
@@ -182,6 +189,48 @@ namespace gr {
d_main_gui->resize(QSize(width, height));
}
+ std::string
+ time_sink_f_impl::title()
+ {
+ return d_main_gui->title().toStdString();
+ }
+
+ std::string
+ time_sink_f_impl::line_label(int which)
+ {
+ return d_main_gui->lineLabel(which).toStdString();
+ }
+
+ std::string
+ time_sink_f_impl::line_color(int which)
+ {
+ return d_main_gui->lineColor(which).toStdString();
+ }
+
+ int
+ time_sink_f_impl::line_width(int which)
+ {
+ return d_main_gui->lineWidth(which);
+ }
+
+ int
+ time_sink_f_impl::line_style(int which)
+ {
+ return d_main_gui->lineStyle(which);
+ }
+
+ int
+ time_sink_f_impl::line_marker(int which)
+ {
+ return d_main_gui->lineMarker(which);
+ }
+
+ double
+ time_sink_f_impl::line_alpha(int which)
+ {
+ return (double)(d_main_gui->markerAlpha(which))/255.0;
+ }
+
void
time_sink_f_impl::set_nsamps(const int newsize)
{
@@ -227,6 +276,24 @@ namespace gr {
}
void
+ time_sink_f_impl::toggle_stem_plot()
+ {
+ d_main_gui->setStem();
+ }
+
+ void
+ time_sink_f_impl::enable_menu(bool en)
+ {
+ d_main_gui->enableMenu(en);
+ }
+
+ void
+ time_sink_f_impl::enable_grid(bool en)
+ {
+ d_main_gui->setGrid(en);
+ }
+
+ void
time_sink_f_impl::reset()
{
d_index = 0;
diff --git a/gr-qtgui/lib/time_sink_f_impl.h b/gr-qtgui/lib/time_sink_f_impl.h
index 065397bb78..b6aafb19b7 100644
--- a/gr-qtgui/lib/time_sink_f_impl.h
+++ b/gr-qtgui/lib/time_sink_f_impl.h
@@ -73,15 +73,27 @@ namespace gr {
void set_line_label(int which, const std::string &label);
void set_line_color(int which, const std::string &color);
void set_line_width(int which, int width);
- void set_line_style(int which, Qt::PenStyle style);
- void set_line_marker(int which, QwtSymbol::Style marker);
+ void set_line_style(int which, int style);
+ void set_line_marker(int which, int marker);
void set_nsamps(const int newsize);
void set_samp_rate(const double samp_rate);
+ void set_line_alpha(int which, double alpha);
+
+ std::string title();
+ std::string line_label(int which);
+ std::string line_color(int which);
+ int line_width(int which);
+ int line_style(int which);
+ int line_marker(int which);
+ double line_alpha(int which);
void set_size(int width, int height);
int nsamps() const;
+ void enable_menu(bool en);
+ void enable_grid(bool en);
+ void toggle_stem_plot();
void reset();
int work(int noutput_items,
diff --git a/gr-qtgui/lib/timedisplayform.cc b/gr-qtgui/lib/timedisplayform.cc
index 11ceefff3e..95bcde4f27 100644
--- a/gr-qtgui/lib/timedisplayform.cc
+++ b/gr-qtgui/lib/timedisplayform.cc
@@ -28,6 +28,8 @@
TimeDisplayForm::TimeDisplayForm(int nplots, QWidget* parent)
: DisplayForm(nplots, parent)
{
+ d_stem = false;
+
_intValidator = new QIntValidator(this);
_intValidator->setBottom(0);
@@ -41,6 +43,11 @@ TimeDisplayForm::TimeDisplayForm(int nplots, QWidget* parent)
connect(nptsmenu, SIGNAL(whichTrigger(int)),
this, SLOT(setNPoints(const int)));
+ QAction *stemmenu = new QAction("Stem Plot", this);
+ _menu->addAction(stemmenu);
+ connect(stemmenu, SIGNAL(triggered(bool)),
+ this, SLOT(setStem(bool)));
+
Reset();
connect(_displayPlot, SIGNAL(plotPointSelected(const QPointF)),
@@ -115,3 +122,10 @@ TimeDisplayForm::setNPoints(const int npoints)
{
d_npoints = npoints;
}
+
+void
+TimeDisplayForm::setStem(bool trig)
+{
+ d_stem ^= 1;
+ getPlot()->stemPlot(d_stem);
+}
diff --git a/gr-qtgui/lib/timedisplayform.h b/gr-qtgui/lib/timedisplayform.h
index df8803c145..f8d059e388 100644
--- a/gr-qtgui/lib/timedisplayform.h
+++ b/gr-qtgui/lib/timedisplayform.h
@@ -48,6 +48,7 @@ public slots:
void setSampleRate(const double samprate);
void setYaxis(double min, double max);
void setNPoints(const int);
+ void setStem(bool trig=false);
private slots:
void newData(const QEvent*);
@@ -59,6 +60,8 @@ private:
double _stopFrequency;
int d_npoints;
+
+ bool d_stem;
};
#endif /* TIME_DISPLAY_FORM_H */
diff --git a/gr-qtgui/lib/waterfall_sink_c_impl.cc b/gr-qtgui/lib/waterfall_sink_c_impl.cc
index 99a9d89dc9..e182d3c141 100644
--- a/gr-qtgui/lib/waterfall_sink_c_impl.cc
+++ b/gr-qtgui/lib/waterfall_sink_c_impl.cc
@@ -28,6 +28,7 @@
#include <gr_io_signature.h>
#include <string.h>
#include <volk/volk.h>
+#include <qwt_symbol.h>
namespace gr {
namespace qtgui {
@@ -36,25 +37,28 @@ namespace gr {
waterfall_sink_c::make(int fftsize, int wintype,
double fc, double bw,
const std::string &name,
+ int nconnections,
QWidget *parent)
{
return gnuradio::get_initial_sptr
(new waterfall_sink_c_impl(fftsize, wintype,
fc, bw, name,
+ nconnections,
parent));
}
waterfall_sink_c_impl::waterfall_sink_c_impl(int fftsize, int wintype,
double fc, double bw,
const std::string &name,
+ int nconnections,
QWidget *parent)
: gr_sync_block("waterfall_sink_c",
- gr_make_io_signature(1, -1, sizeof(gr_complex)),
+ gr_make_io_signature(1, nconnections, sizeof(gr_complex)),
gr_make_io_signature(0, 0, 0)),
d_fftsize(fftsize), d_fftavg(1.0),
d_wintype((filter::firdes::win_type)(wintype)),
d_center_freq(fc), d_bandwidth(bw), d_name(name),
- d_nconnections(1), d_parent(parent)
+ d_nconnections(nconnections), d_parent(parent)
{
d_main_gui = NULL;
@@ -117,7 +121,7 @@ namespace gr {
}
d_main_gui = new WaterfallDisplayForm(d_nconnections, d_parent);
- d_main_gui->setFFTWindowType(d_wintype);
+ set_fft_window(d_wintype);
set_fft_size(d_fftsize);
set_frequency_range(d_center_freq, d_bandwidth);
@@ -147,9 +151,14 @@ namespace gr {
}
void
+ waterfall_sink_c_impl::clear_data()
+ {
+ d_main_gui->clearData();
+ }
+
+ void
waterfall_sink_c_impl::set_fft_size(const int fftsize)
{
- d_fftsize = fftsize;
d_main_gui->setFFTSize(fftsize);
}
@@ -162,7 +171,6 @@ namespace gr {
void
waterfall_sink_c_impl::set_fft_average(const float fftavg)
{
- d_fftavg = fftavg;
d_main_gui->setFFTAverage(fftavg);
}
@@ -173,6 +181,18 @@ namespace gr {
}
void
+ waterfall_sink_c_impl::set_fft_window(const filter::firdes::win_type win)
+ {
+ d_main_gui->setFFTWindowType(win);
+ }
+
+ filter::firdes::win_type
+ waterfall_sink_c_impl::fft_window()
+ {
+ return d_wintype;
+ }
+
+ void
waterfall_sink_c_impl::set_frequency_range(const double centerfreq,
const double bandwidth)
{
@@ -182,6 +202,13 @@ namespace gr {
}
void
+ waterfall_sink_c_impl::set_intensity_range(const double min,
+ const double max)
+ {
+ d_main_gui->setIntensityRange(min, max);
+ }
+
+ void
waterfall_sink_c_impl::set_update_time(double t)
{
//convert update time to ticks
@@ -197,39 +224,81 @@ namespace gr {
}
void
- waterfall_sink_c_impl::set_line_label(const std::string &label)
+ waterfall_sink_c_impl::set_line_label(int which, const std::string &label)
+ {
+ d_main_gui->setLineLabel(which, label.c_str());
+ }
+
+ void
+ waterfall_sink_c_impl::set_color_map(int which, const int color)
{
- d_main_gui->setLineLabel(0, label.c_str());
+ d_main_gui->setColorMap(which, color);
}
void
- waterfall_sink_c_impl::set_line_color(const std::string &color)
+ waterfall_sink_c_impl::set_line_alpha(int which, double alpha)
{
- d_main_gui->setLineColor(0, color.c_str());
+ d_main_gui->setAlpha(which, (int)(255.0*alpha));
}
void
- waterfall_sink_c_impl::set_line_width(int width)
+ waterfall_sink_c_impl::set_size(int width, int height)
+ {
+ d_main_gui->resize(QSize(width, height));
+ }
+
+ std::string
+ waterfall_sink_c_impl::title()
+ {
+ return d_main_gui->title().toStdString();
+ }
+
+ std::string
+ waterfall_sink_c_impl::line_label(int which)
{
- d_main_gui->setLineWidth(0, width);
+ return d_main_gui->lineLabel(which).toStdString();
+ }
+
+ int
+ waterfall_sink_c_impl::color_map(int which)
+ {
+ return d_main_gui->getColorMap(which);
+ }
+
+ double
+ waterfall_sink_c_impl::line_alpha(int which)
+ {
+ return (double)(d_main_gui->markerAlpha(which))/255.0;
}
void
- waterfall_sink_c_impl::set_line_style(Qt::PenStyle style)
+ waterfall_sink_c_impl::auto_scale()
+ {
+ d_main_gui->autoScale();
+ }
+
+ double
+ waterfall_sink_c_impl::min_intensity(int which)
{
- d_main_gui->setLineStyle(0, style);
+ return d_main_gui->getMinIntensity(which);
+ }
+
+ double
+ waterfall_sink_c_impl::max_intensity(int which)
+ {
+ return d_main_gui->getMaxIntensity(which);
}
void
- waterfall_sink_c_impl::set_line_marker(QwtSymbol::Style marker)
+ waterfall_sink_c_impl::enable_menu(bool en)
{
- d_main_gui->setLineMarker(0, marker);
+ d_main_gui->enableMenu(en);
}
void
- waterfall_sink_c_impl::set_size(int width, int height)
+ waterfall_sink_c_impl::enable_grid(bool en)
{
- d_main_gui->resize(QSize(width, height));
+ d_main_gui->setGrid(en);
}
void
diff --git a/gr-qtgui/lib/waterfall_sink_c_impl.h b/gr-qtgui/lib/waterfall_sink_c_impl.h
index 3356059bc4..1d709c6c5f 100644
--- a/gr-qtgui/lib/waterfall_sink_c_impl.h
+++ b/gr-qtgui/lib/waterfall_sink_c_impl.h
@@ -72,6 +72,7 @@ namespace gr {
waterfall_sink_c_impl(int size, int wintype,
double fc, double bw,
const std::string &name,
+ int nconnections,
QWidget *parent=NULL);
~waterfall_sink_c_impl();
@@ -81,23 +82,38 @@ namespace gr {
QWidget* qwidget();
PyObject* pyqwidget();
+ void clear_data();
+
void set_fft_size(const int fftsize);
int fft_size() const;
void set_fft_average(const float fftavg);
float fft_average() const;
+ void set_fft_window(const gr::filter::firdes::win_type win);
+ gr::filter::firdes::win_type fft_window();
void set_frequency_range(const double centerfreq, const double bandwidth);
+ void set_intensity_range(const double min, const double max);
void set_update_time(double t);
void set_title(const std::string &title);
- void set_line_label(const std::string &label);
- void set_line_color(const std::string &color);
- void set_line_width(int width);
- void set_line_style(Qt::PenStyle style);
- void set_line_marker(QwtSymbol::Style marker);
+ void set_line_label(int which, const std::string &label);
+ void set_line_alpha(int which, double alpha);
+ void set_color_map(int which, const int color);
+
+ std::string title();
+ std::string line_label(int which);
+ double line_alpha(int which);
+ int color_map(int which);
void set_size(int width, int height);
+ void auto_scale();
+ double min_intensity(int which);
+ double max_intensity(int which);
+
+ void enable_menu(bool en);
+ void enable_grid(bool en);
+
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
diff --git a/gr-qtgui/lib/waterfall_sink_f_impl.cc b/gr-qtgui/lib/waterfall_sink_f_impl.cc
index 6d4888f5e7..d59319fd27 100644
--- a/gr-qtgui/lib/waterfall_sink_f_impl.cc
+++ b/gr-qtgui/lib/waterfall_sink_f_impl.cc
@@ -36,17 +36,20 @@ namespace gr {
waterfall_sink_f::make(int fftsize, int wintype,
double fc, double bw,
const std::string &name,
+ int nconnections,
QWidget *parent)
{
return gnuradio::get_initial_sptr
(new waterfall_sink_f_impl(fftsize, wintype,
fc, bw, name,
+ nconnections,
parent));
}
waterfall_sink_f_impl::waterfall_sink_f_impl(int fftsize, int wintype,
double fc, double bw,
const std::string &name,
+ int nconnections,
QWidget *parent)
: gr_sync_block("waterfall_sink_f",
gr_make_io_signature(1, -1, sizeof(float)),
@@ -54,7 +57,7 @@ namespace gr {
d_fftsize(fftsize), d_fftavg(1.0),
d_wintype((filter::firdes::win_type)(wintype)),
d_center_freq(fc), d_bandwidth(bw), d_name(name),
- d_nconnections(1), d_parent(parent)
+ d_nconnections(nconnections), d_parent(parent)
{
d_main_gui = NULL;
@@ -117,7 +120,7 @@ namespace gr {
}
d_main_gui = new WaterfallDisplayForm(d_nconnections, d_parent);
- d_main_gui->setFFTWindowType(d_wintype);
+ set_fft_window(d_wintype);
set_fft_size(d_fftsize);
set_frequency_range(d_center_freq, d_bandwidth);
@@ -147,9 +150,14 @@ namespace gr {
}
void
+ waterfall_sink_f_impl::clear_data()
+ {
+ d_main_gui->clearData();
+ }
+
+ void
waterfall_sink_f_impl::set_fft_size(const int fftsize)
{
- d_fftsize = fftsize;
d_main_gui->setFFTSize(fftsize);
}
@@ -162,7 +170,6 @@ namespace gr {
void
waterfall_sink_f_impl::set_fft_average(const float fftavg)
{
- d_fftavg = fftavg;
d_main_gui->setFFTAverage(fftavg);
}
@@ -173,6 +180,18 @@ namespace gr {
}
void
+ waterfall_sink_f_impl::set_fft_window(const filter::firdes::win_type win)
+ {
+ d_main_gui->setFFTWindowType(win);
+ }
+
+ filter::firdes::win_type
+ waterfall_sink_f_impl::fft_window()
+ {
+ return d_wintype;
+ }
+
+ void
waterfall_sink_f_impl::set_frequency_range(const double centerfreq,
const double bandwidth)
{
@@ -182,6 +201,13 @@ namespace gr {
}
void
+ waterfall_sink_f_impl::set_intensity_range(const double min,
+ const double max)
+ {
+ d_main_gui->setIntensityRange(min, max);
+ }
+
+ void
waterfall_sink_f_impl::set_update_time(double t)
{
//convert update time to ticks
@@ -197,39 +223,81 @@ namespace gr {
}
void
- waterfall_sink_f_impl::set_line_label(const std::string &label)
+ waterfall_sink_f_impl::set_line_label(int which, const std::string &label)
+ {
+ d_main_gui->setLineLabel(which, label.c_str());
+ }
+
+ void
+ waterfall_sink_f_impl::set_color_map(int which, const int color)
{
- d_main_gui->setLineLabel(0, label.c_str());
+ d_main_gui->setColorMap(which, color);
}
void
- waterfall_sink_f_impl::set_line_color(const std::string &color)
+ waterfall_sink_f_impl::set_line_alpha(int which, double alpha)
{
- d_main_gui->setLineColor(0, color.c_str());
+ d_main_gui->setAlpha(which, (int)(255.0*alpha));
}
void
- waterfall_sink_f_impl::set_line_width(int width)
+ waterfall_sink_f_impl::set_size(int width, int height)
+ {
+ d_main_gui->resize(QSize(width, height));
+ }
+
+ std::string
+ waterfall_sink_f_impl::title()
+ {
+ return d_main_gui->title().toStdString();
+ }
+
+ std::string
+ waterfall_sink_f_impl::line_label(int which)
{
- d_main_gui->setLineWidth(0, width);
+ return d_main_gui->lineLabel(which).toStdString();
+ }
+
+ int
+ waterfall_sink_f_impl::color_map(int which)
+ {
+ return d_main_gui->getColorMap(which);
+ }
+
+ double
+ waterfall_sink_f_impl::line_alpha(int which)
+ {
+ return (double)(d_main_gui->getAlpha(which))/255.0;
}
void
- waterfall_sink_f_impl::set_line_style(Qt::PenStyle style)
+ waterfall_sink_f_impl::auto_scale()
+ {
+ d_main_gui->autoScale();
+ }
+
+ double
+ waterfall_sink_f_impl::min_intensity(int which)
{
- d_main_gui->setLineStyle(0, style);
+ return d_main_gui->getMinIntensity(which);
+ }
+
+ double
+ waterfall_sink_f_impl::max_intensity(int which)
+ {
+ return d_main_gui->getMaxIntensity(which);
}
void
- waterfall_sink_f_impl::set_line_marker(QwtSymbol::Style marker)
+ waterfall_sink_f_impl::enable_menu(bool en)
{
- d_main_gui->setLineMarker(0, marker);
+ d_main_gui->enableMenu(en);
}
void
- waterfall_sink_f_impl::set_size(int width, int height)
+ waterfall_sink_f_impl::enable_grid(bool en)
{
- d_main_gui->resize(QSize(width, height));
+ d_main_gui->setGrid(en);
}
void
diff --git a/gr-qtgui/lib/waterfall_sink_f_impl.h b/gr-qtgui/lib/waterfall_sink_f_impl.h
index 6043363545..6185a25397 100644
--- a/gr-qtgui/lib/waterfall_sink_f_impl.h
+++ b/gr-qtgui/lib/waterfall_sink_f_impl.h
@@ -71,9 +71,10 @@ namespace gr {
public:
waterfall_sink_f_impl(int size, int wintype,
- double fc, double bw,
- const std::string &name,
- QWidget *parent=NULL);
+ double fc, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent=NULL);
~waterfall_sink_f_impl();
bool check_topology(int ninputs, int noutputs);
@@ -82,23 +83,38 @@ namespace gr {
QWidget* qwidget();
PyObject* pyqwidget();
+ void clear_data();
+
void set_fft_size(const int fftsize);
int fft_size() const;
void set_fft_average(const float fftavg);
float fft_average() const;
+ void set_fft_window(const gr::filter::firdes::win_type win);
+ gr::filter::firdes::win_type fft_window();
void set_frequency_range(const double centerfreq, const double bandwidth);
+ void set_intensity_range(const double min, const double max);
void set_update_time(double t);
void set_title(const std::string &title);
- void set_line_label(const std::string &label);
- void set_line_color(const std::string &color);
- void set_line_width(int width);
- void set_line_style(Qt::PenStyle style);
- void set_line_marker(QwtSymbol::Style marker);
+ void set_line_label(int which, const std::string &label);
+ void set_line_alpha(int which, double alpha);
+ void set_color_map(int which, const int color);
+
+ std::string title();
+ std::string line_label(int which);
+ double line_alpha(int which);
+ int color_map(int which);
void set_size(int width, int height);
+ void auto_scale();
+ double min_intensity(int which);
+ double max_intensity(int which);
+
+ void enable_menu(bool en);
+ void enable_grid(bool en);
+
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
diff --git a/gr-qtgui/lib/waterfalldisplayform.cc b/gr-qtgui/lib/waterfalldisplayform.cc
index e8e78ea3de..480f18d5b1 100644
--- a/gr-qtgui/lib/waterfalldisplayform.cc
+++ b/gr-qtgui/lib/waterfalldisplayform.cc
@@ -44,6 +44,31 @@ WaterfallDisplayForm::WaterfallDisplayForm(int nplots, QWidget* parent)
_min_val = 1000;
_max_val = -1000;
+ // We don't use the normal menus that are part of the displayform.
+ // Clear them out to get rid of their resources.
+ for(int i = 0; i < nplots; i++) {
+ _lines_menu[i]->clear();
+ }
+ _line_title_act.clear();
+ _line_color_menu.clear();
+ _line_width_menu.clear();
+ _line_style_menu.clear();
+ _line_marker_menu.clear();
+ _marker_alpha_menu.clear();
+
+ // Now create our own menus
+ for(int i = 0; i < nplots; i++) {
+ ColorMapMenu *colormap = new ColorMapMenu(i, this);
+ connect(colormap, SIGNAL(whichTrigger(int, const int, const QColor&, const QColor&)),
+ this, SLOT(setColorMap(int, const int, const QColor&, const QColor&)));
+ _lines_menu[i]->addMenu(colormap);
+
+ _marker_alpha_menu.push_back(new MarkerAlphaMenu(i, this));
+ connect(_marker_alpha_menu[i], SIGNAL(whichTrigger(int, int)),
+ this, SLOT(setAlpha(int, int)));
+ _lines_menu[i]->addMenu(_marker_alpha_menu[i]);
+ }
+
QAction *autoscale_act = new QAction("Auto Scale", this);
autoscale_act->setStatusTip(tr("Autoscale intensity range"));
connect(autoscale_act, SIGNAL(triggered()), this, SLOT(autoScale()));
@@ -51,11 +76,9 @@ WaterfallDisplayForm::WaterfallDisplayForm(int nplots, QWidget* parent)
FFTSizeMenu *sizemenu = new FFTSizeMenu(this);
FFTAverageMenu *avgmenu = new FFTAverageMenu(this);
FFTWindowMenu *winmenu = new FFTWindowMenu(this);
- ColorMapMenu *colormenu = new ColorMapMenu(this);
_menu->addMenu(sizemenu);
_menu->addMenu(avgmenu);
_menu->addMenu(winmenu);
- _menu->addMenu(colormenu);
_menu->addAction(autoscale_act);
connect(sizemenu, SIGNAL(whichTrigger(int)),
this, SLOT(setFFTSize(const int)));
@@ -63,8 +86,6 @@ WaterfallDisplayForm::WaterfallDisplayForm(int nplots, QWidget* parent)
this, SLOT(setFFTAverage(const float)));
connect(winmenu, SIGNAL(whichTrigger(gr::filter::firdes::win_type)),
this, SLOT(setFFTWindowType(const gr::filter::firdes::win_type)));
- connect(colormenu, SIGNAL(whichTrigger(const int, const QColor&, const QColor&)),
- this, SLOT(setColorMap(const int, const QColor&, const QColor&)));
Reset();
@@ -106,7 +127,7 @@ WaterfallDisplayForm::newData(const QEvent *updateEvent)
}
getPlot()->plotNewData(dataPoints, numDataPoints,
- d_update_time, dataTimestamp, 0);
+ _time_per_slice, dataTimestamp, 0);
}
void
@@ -135,6 +156,30 @@ WaterfallDisplayForm::getFFTWindowType() const
return _fftwintype;
}
+int
+WaterfallDisplayForm::getColorMap(int which)
+{
+ return getPlot()->getIntensityColorMapType(which);
+}
+
+int
+WaterfallDisplayForm::getAlpha(int which)
+{
+ return getPlot()->getAlpha(which);
+}
+
+double
+WaterfallDisplayForm::getMinIntensity(int which)
+{
+ return getPlot()->getMinIntensity(which);
+}
+
+double
+WaterfallDisplayForm::getMaxIntensity(int which)
+{
+ return getPlot()->getMaxIntensity(which);
+}
+
void
WaterfallDisplayForm::setFFTSize(const int newsize)
{
@@ -163,17 +208,30 @@ WaterfallDisplayForm::setFrequencyRange(const double centerfreq,
double units = pow(10, (units10-fmod(units10, 3.0)));
int iunit = static_cast<int>(units3);
+ _samp_rate = bandwidth;
+ _time_per_slice = (1.0/bandwidth)*_fftsize;
+
getPlot()->setFrequencyRange(centerfreq, bandwidth,
units, strunits[iunit]);
+ getPlot()->replot();
}
void
-WaterfallDisplayForm::setColorMap(const int newType,
+WaterfallDisplayForm::setColorMap(int which,
+ const int newType,
const QColor lowColor,
const QColor highColor)
{
- getPlot()->setIntensityColorMapType(0, newType,
+ getPlot()->setIntensityColorMapType(which, newType,
lowColor, highColor);
+ getPlot()->replot();
+}
+
+void
+WaterfallDisplayForm::setAlpha(int which, int alpha)
+{
+ getPlot()->setAlpha(which, alpha);
+ getPlot()->replot();
}
void
@@ -181,6 +239,7 @@ WaterfallDisplayForm::setIntensityRange(const double minIntensity,
const double maxIntensity)
{
getPlot()->setIntensityRange(minIntensity, maxIntensity);
+ getPlot()->replot();
}
void
@@ -190,4 +249,11 @@ WaterfallDisplayForm::autoScale()
double max_int = _max_val + 10;
getPlot()->setIntensityRange(min_int, max_int);
+ getPlot()->replot();
+}
+
+void
+WaterfallDisplayForm::clearData()
+{
+ getPlot()->clearData();
}
diff --git a/gr-qtgui/lib/waterfalldisplayform.h b/gr-qtgui/lib/waterfalldisplayform.h
index e078aeb05a..a6add831fd 100644
--- a/gr-qtgui/lib/waterfalldisplayform.h
+++ b/gr-qtgui/lib/waterfalldisplayform.h
@@ -45,6 +45,13 @@ class WaterfallDisplayForm : public DisplayForm
float getFFTAverage() const;
gr::filter::firdes::win_type getFFTWindowType() const;
+ int getColorMap(int which);
+ int getAlpha(int which);
+ double getMinIntensity(int which);
+ double getMaxIntensity(int which);
+
+ void clearData();
+
public slots:
void customEvent(QEvent *e);
@@ -58,9 +65,12 @@ public slots:
void setIntensityRange(const double minIntensity,
const double maxIntensity);
- void setColorMap(const int newType,
- const QColor lowColor,
- const QColor highColor);
+ void setAlpha(int which, int alpha);
+
+ void setColorMap(int which,
+ const int newType,
+ const QColor lowColor=QColor("white"),
+ const QColor highColor=QColor("white"));
void autoScale();
@@ -71,6 +81,8 @@ private:
uint64_t _numRealDataPoints;
QIntValidator* _intValidator;
+ double _samp_rate;
+ double _time_per_slice;
int _fftsize;
float _fftavg;
gr::filter::firdes::win_type _fftwintype;
diff --git a/gr-qtgui/swig/CMakeLists.txt b/gr-qtgui/swig/CMakeLists.txt
index e2beb5327e..d17130597e 100644
--- a/gr-qtgui/swig/CMakeLists.txt
+++ b/gr-qtgui/swig/CMakeLists.txt
@@ -26,6 +26,7 @@ include(GrSwig)
set(GR_SWIG_INCLUDE_DIRS
${GR_QTGUI_INCLUDE_DIRS}
${GR_FFT_INCLUDE_DIRS}
+ ${GR_FILTER_INCLUDE_DIRS}
${GNURADIO_CORE_SWIG_INCLUDE_DIRS}
${GRUEL_INCLUDE_DIRS}
${QWT_INCLUDE_DIRS}
diff --git a/gr-qtgui/swig/qtgui_swig.i b/gr-qtgui/swig/qtgui_swig.i
index 9821ccf440..20675503e2 100644
--- a/gr-qtgui/swig/qtgui_swig.i
+++ b/gr-qtgui/swig/qtgui_swig.i
@@ -21,12 +21,16 @@
*/
#define QTGUI_API
+#define FILTER_API
%include "gnuradio.i"
//load generated python docstrings
%include "qtgui_swig_doc.i"
+// So we understand the firdes window types
+%include "filter/firdes.h"
+
%{
#include "qtgui/sink_c.h"
#include "qtgui/sink_f.h"