diff options
author | Tom Rondeau <trondeau@vt.edu> | 2012-07-29 14:19:09 -0400 |
---|---|---|
committer | Tom Rondeau <trondeau@vt.edu> | 2012-07-29 14:19:09 -0400 |
commit | eb4305b92f0128c47743b4e2df032a04052ac21d (patch) | |
tree | f89afd36f050587b943839162e65922de4ca86f5 /gr-qtgui/apps/gr_spectrogram_plot_c | |
parent | 0eea9a33a1a57473973709662eb734d54df647fa (diff) |
qtgui: introduces new static plot tools for different data types.
Time, PSD, and Spectrogram have tools for char, short, int, float, and complex data types. Constellation requires complex inputs.
These tools are now installed into the runtime bin directory.
Diffstat (limited to 'gr-qtgui/apps/gr_spectrogram_plot_c')
-rwxr-xr-x | gr-qtgui/apps/gr_spectrogram_plot_c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/gr-qtgui/apps/gr_spectrogram_plot_c b/gr-qtgui/apps/gr_spectrogram_plot_c new file mode 100755 index 0000000000..28fa82f298 --- /dev/null +++ b/gr-qtgui/apps/gr_spectrogram_plot_c @@ -0,0 +1,176 @@ +#!/usr/bin/env python +# +# Copyright 2012 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 +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 * +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): + 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_gr_complex, self._start) + self.add = gr.add_cc() + 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() + +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) + + filelist = list(args) + + 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); + + main_box = dialog_box(tb, 'GNU Radio Spectrogram Plot') + main_box.show() + + tb.run() + tb.qapp.exec_() + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + pass + |