From f41530726eb2ef70a4683faa9f5e4760b67d7d5f Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Thu, 21 Apr 2011 19:11:03 -0400 Subject: gr-qtgui: adding time-domain only plotter. --- gr-qtgui/lib/qtgui_time_sink_c.cc | 178 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 gr-qtgui/lib/qtgui_time_sink_c.cc (limited to 'gr-qtgui/lib/qtgui_time_sink_c.cc') diff --git a/gr-qtgui/lib/qtgui_time_sink_c.cc b/gr-qtgui/lib/qtgui_time_sink_c.cc new file mode 100644 index 000000000..d6e6f0a13 --- /dev/null +++ b/gr-qtgui/lib/qtgui_time_sink_c.cc @@ -0,0 +1,178 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +qtgui_time_sink_c_sptr +qtgui_make_time_sink_c (int size, double bw, + const std::string &name, + QWidget *parent) +{ + return gnuradio::get_initial_sptr(new qtgui_time_sink_c (size, bw, name, + parent)); +} + +qtgui_time_sink_c::qtgui_time_sink_c (int size, double bw, + const std::string &name, + QWidget *parent) + : gr_block ("time_sink_c", + gr_make_io_signature (1, -1, sizeof(gr_complex)), + gr_make_io_signature (0, 0, 0)), + d_size(size), d_bandwidth(bw), d_name(name), + d_parent(parent) +{ + d_main_gui = NULL; + + d_index = 0; + d_residbuf = new gr_complex[d_size]; + + initialize(); +} + +qtgui_time_sink_c::~qtgui_time_sink_c() +{ + delete d_main_gui; + delete [] d_residbuf; +} + +void +qtgui_time_sink_c::forecast(int noutput_items, gr_vector_int &ninput_items_required) +{ + unsigned int ninputs = ninput_items_required.size(); + for (unsigned int i = 0; i < ninputs; i++) { + ninput_items_required[i] = std::min(d_size, 8191); + } +} + +void +qtgui_time_sink_c::initialize() +{ + if(qApp != NULL) { + d_qApplication = qApp; + } + else { + int argc=0; + char **argv = NULL; + d_qApplication = new QApplication(argc, argv); + } + + /* + uint64_t maxBufferSize = 32768; + d_main_gui = new SpectrumGUIClass(maxBufferSize, d_fftsize, + d_center_freq, + -d_bandwidth/2.0, + d_bandwidth/2.0); + + d_main_gui->SetDisplayTitle(d_name); + d_main_gui->SetFFTSize(d_size); + + d_main_gui->OpenSpectrumWindow(d_parent, + d_plotfreq, d_plotwaterfall, + d_plottime, d_plotconst); + */ + + d_main_gui = new TimeDisplayForm(d_parent); + + // initialize update time to 10 times a second + set_update_time(0.1); +} + + +void +qtgui_time_sink_c::exec_() +{ + d_qApplication->exec(); +} + +QWidget* +qtgui_time_sink_c::qwidget() +{ + return d_main_gui; +} + +PyObject* +qtgui_time_sink_c::pyqwidget() +{ + PyObject *w = PyLong_FromVoidPtr((void*)d_main_gui); + PyObject *retarg = Py_BuildValue("N", w); + return retarg; +} + +void +qtgui_time_sink_c::set_time_domain_axis(double min, double max) +{ + d_main_gui->SetTimeDomainAxis(min, max); +} + +void +qtgui_time_sink_c::set_update_time(double t) +{ + d_update_time = t; + d_main_gui->SetUpdateTime(d_update_time); +} + +int +qtgui_time_sink_c::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + int j=0; + const gr_complex *in = (const gr_complex*)input_items[0]; + + for(int i=0; i < noutput_items; i+=d_size) { + unsigned int datasize = noutput_items - i; + unsigned int resid = d_size-d_index; + + // If we have enough input for one full FFT, do it + if(datasize >= resid) { + const timespec currentTime = get_highres_clock(); + + // Fill up residbuf with d_fftsize number of items + memcpy(d_residbuf+d_index, &in[j], sizeof(gr_complex)*resid); + d_index = 0; + + j += resid; + + d_qApplication->postEvent(d_main_gui, + new TimeUpdateEvent(d_residbuf, d_size, + currentTime, true)); + } + // Otherwise, copy what we received into the residbuf for next time + else { + memcpy(d_residbuf+d_index, &in[j], sizeof(gr_complex)*datasize); + d_index += datasize; + j += datasize; + } + } + + consume_each(j); + return j; +} -- cgit From 240ff2e7468d1651ad0b7557c061bb46aed8a4a3 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sat, 23 Apr 2011 11:29:15 -0400 Subject: gr-qtgui: cleaning up; don't delete d_main_gui. --- gr-qtgui/lib/qtgui_time_sink_c.cc | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'gr-qtgui/lib/qtgui_time_sink_c.cc') diff --git a/gr-qtgui/lib/qtgui_time_sink_c.cc b/gr-qtgui/lib/qtgui_time_sink_c.cc index d6e6f0a13..064463162 100644 --- a/gr-qtgui/lib/qtgui_time_sink_c.cc +++ b/gr-qtgui/lib/qtgui_time_sink_c.cc @@ -58,7 +58,7 @@ qtgui_time_sink_c::qtgui_time_sink_c (int size, double bw, qtgui_time_sink_c::~qtgui_time_sink_c() { - delete d_main_gui; + // d_main_gui is a qwidget destroyed with its parent delete [] d_residbuf; } @@ -83,21 +83,6 @@ qtgui_time_sink_c::initialize() d_qApplication = new QApplication(argc, argv); } - /* - uint64_t maxBufferSize = 32768; - d_main_gui = new SpectrumGUIClass(maxBufferSize, d_fftsize, - d_center_freq, - -d_bandwidth/2.0, - d_bandwidth/2.0); - - d_main_gui->SetDisplayTitle(d_name); - d_main_gui->SetFFTSize(d_size); - - d_main_gui->OpenSpectrumWindow(d_parent, - d_plotfreq, d_plotwaterfall, - d_plottime, d_plotconst); - */ - d_main_gui = new TimeDisplayForm(d_parent); // initialize update time to 10 times a second -- cgit From bbb5e850224aca9dae15d24bd898cc56232327c9 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sat, 23 Apr 2011 12:00:54 -0400 Subject: gr-qtgui: setting up ability to have multiple connections to the time sink. --- gr-qtgui/lib/qtgui_time_sink_c.cc | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'gr-qtgui/lib/qtgui_time_sink_c.cc') diff --git a/gr-qtgui/lib/qtgui_time_sink_c.cc b/gr-qtgui/lib/qtgui_time_sink_c.cc index 064463162..cff265835 100644 --- a/gr-qtgui/lib/qtgui_time_sink_c.cc +++ b/gr-qtgui/lib/qtgui_time_sink_c.cc @@ -33,25 +33,30 @@ qtgui_time_sink_c_sptr qtgui_make_time_sink_c (int size, double bw, const std::string &name, + int nconnections, QWidget *parent) { return gnuradio::get_initial_sptr(new qtgui_time_sink_c (size, bw, name, - parent)); + nconnections, parent)); } qtgui_time_sink_c::qtgui_time_sink_c (int size, double bw, const std::string &name, + int nconnections, QWidget *parent) : gr_block ("time_sink_c", - gr_make_io_signature (1, -1, sizeof(gr_complex)), + gr_make_io_signature (nconnections, nconnections, sizeof(gr_complex)), gr_make_io_signature (0, 0, 0)), d_size(size), d_bandwidth(bw), d_name(name), - d_parent(parent) + d_nconnections(nconnections), d_parent(parent) { d_main_gui = NULL; d_index = 0; - d_residbuf = new gr_complex[d_size]; + + for(int i = 0; i < d_nconnections; i++) { + d_residbufs.push_back(new gr_complex[d_size]); + } initialize(); } @@ -59,7 +64,9 @@ qtgui_time_sink_c::qtgui_time_sink_c (int size, double bw, qtgui_time_sink_c::~qtgui_time_sink_c() { // d_main_gui is a qwidget destroyed with its parent - delete [] d_residbuf; + for(int i = 0; i < d_nconnections; i++) { + delete [] d_residbufs[i]; + } } void @@ -129,7 +136,7 @@ qtgui_time_sink_c::general_work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - int j=0; + int n=0, j=0; const gr_complex *in = (const gr_complex*)input_items[0]; for(int i=0; i < noutput_items; i+=d_size) { @@ -140,19 +147,24 @@ qtgui_time_sink_c::general_work (int noutput_items, if(datasize >= resid) { const timespec currentTime = get_highres_clock(); - // Fill up residbuf with d_fftsize number of items - memcpy(d_residbuf+d_index, &in[j], sizeof(gr_complex)*resid); + // Fill up residbufs with d_fftsize number of items + for(n = 0; n < d_nconnections; n++) { + memcpy(d_residbufs[n]+d_index, &in[j], sizeof(gr_complex)*resid); + } + d_index = 0; j += resid; d_qApplication->postEvent(d_main_gui, - new TimeUpdateEvent(d_residbuf, d_size, + new TimeUpdateEvent(d_residbufs, d_size, currentTime, true)); } - // Otherwise, copy what we received into the residbuf for next time + // Otherwise, copy what we received into the residbufs for next time else { - memcpy(d_residbuf+d_index, &in[j], sizeof(gr_complex)*datasize); + for(n = 0; n < d_nconnections; n++) { + memcpy(d_residbufs[n]+d_index, &in[j], sizeof(gr_complex)*datasize); + } d_index += datasize; j += datasize; } -- cgit From 01f44f64c916b4aa38bc81662d2c8b82c4cc0b57 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sat, 23 Apr 2011 14:30:32 -0400 Subject: gr-qtgui: moving towards allowing time plot to have multiple connections. --- gr-qtgui/lib/qtgui_time_sink_c.cc | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'gr-qtgui/lib/qtgui_time_sink_c.cc') diff --git a/gr-qtgui/lib/qtgui_time_sink_c.cc b/gr-qtgui/lib/qtgui_time_sink_c.cc index cff265835..2c8ff86e5 100644 --- a/gr-qtgui/lib/qtgui_time_sink_c.cc +++ b/gr-qtgui/lib/qtgui_time_sink_c.cc @@ -48,14 +48,14 @@ qtgui_time_sink_c::qtgui_time_sink_c (int size, double bw, gr_make_io_signature (nconnections, nconnections, sizeof(gr_complex)), gr_make_io_signature (0, 0, 0)), d_size(size), d_bandwidth(bw), d_name(name), - d_nconnections(nconnections), d_parent(parent) + d_nconnections(2*nconnections), d_parent(parent) { d_main_gui = NULL; d_index = 0; for(int i = 0; i < d_nconnections; i++) { - d_residbufs.push_back(new gr_complex[d_size]); + d_residbufs.push_back(new double[d_size]); } initialize(); @@ -90,7 +90,7 @@ qtgui_time_sink_c::initialize() d_qApplication = new QApplication(argc, argv); } - d_main_gui = new TimeDisplayForm(d_parent); + d_main_gui = new TimeDisplayForm(d_nconnections, d_parent); // initialize update time to 10 times a second set_update_time(0.1); @@ -148,22 +148,30 @@ qtgui_time_sink_c::general_work (int noutput_items, const timespec currentTime = get_highres_clock(); // Fill up residbufs with d_fftsize number of items - for(n = 0; n < d_nconnections; n++) { - memcpy(d_residbufs[n]+d_index, &in[j], sizeof(gr_complex)*resid); + for(n = 0; n < d_nconnections; n+=2) { + for(unsigned int k = 0; k < resid; k++) { + d_residbufs[n][d_index+k] = in[j+k].real(); + d_residbufs[n+1][d_index+k] = in[j+k].imag(); + } + + d_qApplication->postEvent(d_main_gui, + new TimeUpdateEvent(n, d_residbufs[n], d_size, + currentTime, true)); + //d_qApplication->postEvent(d_main_gui, + // new TimeUpdateEvent(n+1, d_residbufs[n+1], d_size, + // currentTime, true)); } d_index = 0; - j += resid; - - d_qApplication->postEvent(d_main_gui, - new TimeUpdateEvent(d_residbufs, d_size, - currentTime, true)); } // Otherwise, copy what we received into the residbufs for next time else { - for(n = 0; n < d_nconnections; n++) { - memcpy(d_residbufs[n]+d_index, &in[j], sizeof(gr_complex)*datasize); + for(n = 0; n < d_nconnections; n+=2) { + for(unsigned int k = 0; k < resid; k++) { + d_residbufs[n][d_index+k] = in[j+k].real(); + d_residbufs[n+1][d_index+k] = in[j+k].imag(); + } } d_index += datasize; j += datasize; -- cgit From 0877adb2e194c9dfad2484519b2979e2bed93958 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sat, 23 Apr 2011 15:11:17 -0400 Subject: gr-qtgui: Passing vectors of data to update plot for stability; also moving responsibility of keeping track of plot updates out to qtgui_sink instead of inside plot qidget. --- gr-qtgui/lib/qtgui_time_sink_c.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'gr-qtgui/lib/qtgui_time_sink_c.cc') diff --git a/gr-qtgui/lib/qtgui_time_sink_c.cc b/gr-qtgui/lib/qtgui_time_sink_c.cc index 2c8ff86e5..434a9dffc 100644 --- a/gr-qtgui/lib/qtgui_time_sink_c.cc +++ b/gr-qtgui/lib/qtgui_time_sink_c.cc @@ -142,26 +142,26 @@ qtgui_time_sink_c::general_work (int noutput_items, for(int i=0; i < noutput_items; i+=d_size) { unsigned int datasize = noutput_items - i; unsigned int resid = d_size-d_index; - - // If we have enough input for one full FFT, do it + + // If we have enough input for one full plot, do it if(datasize >= resid) { - const timespec currentTime = get_highres_clock(); + d_current_time = get_highres_clock(); - // Fill up residbufs with d_fftsize number of items + // Fill up residbufs with d_size number of items for(n = 0; n < d_nconnections; n+=2) { for(unsigned int k = 0; k < resid; k++) { d_residbufs[n][d_index+k] = in[j+k].real(); d_residbufs[n+1][d_index+k] = in[j+k].imag(); } + } + // Update the plot if its time + if(diff_timespec(d_current_time, d_last_time) > d_update_time) { + d_last_time = d_current_time; d_qApplication->postEvent(d_main_gui, - new TimeUpdateEvent(n, d_residbufs[n], d_size, - currentTime, true)); - //d_qApplication->postEvent(d_main_gui, - // new TimeUpdateEvent(n+1, d_residbufs[n+1], d_size, - // currentTime, true)); + new TimeUpdateEvent(d_residbufs, d_size)); } - + d_index = 0; j += resid; } @@ -169,8 +169,8 @@ qtgui_time_sink_c::general_work (int noutput_items, else { for(n = 0; n < d_nconnections; n+=2) { for(unsigned int k = 0; k < resid; k++) { - d_residbufs[n][d_index+k] = in[j+k].real(); - d_residbufs[n+1][d_index+k] = in[j+k].imag(); + d_residbufs[n][d_index+k] = in[j+k].real(); + d_residbufs[n+1][d_index+k] = in[j+k].imag(); } } d_index += datasize; -- cgit From 350611ddd9295ba8af6ea5913630ec0670208b43 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sat, 23 Apr 2011 23:56:52 -0400 Subject: gr-qtgui: multiple connections working, each with their own color. --- gr-qtgui/lib/qtgui_time_sink_c.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'gr-qtgui/lib/qtgui_time_sink_c.cc') diff --git a/gr-qtgui/lib/qtgui_time_sink_c.cc b/gr-qtgui/lib/qtgui_time_sink_c.cc index 434a9dffc..1cd391893 100644 --- a/gr-qtgui/lib/qtgui_time_sink_c.cc +++ b/gr-qtgui/lib/qtgui_time_sink_c.cc @@ -136,12 +136,13 @@ qtgui_time_sink_c::general_work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - int n=0, j=0; - const gr_complex *in = (const gr_complex*)input_items[0]; + int n=0, j=0, idx=0; + const gr_complex *in = (const gr_complex*)input_items[idx]; for(int i=0; i < noutput_items; i+=d_size) { unsigned int datasize = noutput_items - i; unsigned int resid = d_size-d_index; + idx = 0; // If we have enough input for one full plot, do it if(datasize >= resid) { @@ -149,6 +150,7 @@ qtgui_time_sink_c::general_work (int noutput_items, // Fill up residbufs with d_size number of items for(n = 0; n < d_nconnections; n+=2) { + in = (const gr_complex*)input_items[idx++]; for(unsigned int k = 0; k < resid; k++) { d_residbufs[n][d_index+k] = in[j+k].real(); d_residbufs[n+1][d_index+k] = in[j+k].imag(); @@ -168,6 +170,7 @@ qtgui_time_sink_c::general_work (int noutput_items, // Otherwise, copy what we received into the residbufs for next time else { for(n = 0; n < d_nconnections; n+=2) { + in = (const gr_complex*)input_items[idx++]; for(unsigned int k = 0; k < resid; k++) { d_residbufs[n][d_index+k] = in[j+k].real(); d_residbufs[n+1][d_index+k] = in[j+k].imag(); -- cgit From e251c885f19281ef918987e09c2aac1af6a952c2 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 24 Apr 2011 00:31:39 -0400 Subject: gr-qtgui: provide function and slot for setting the labels of a time curve. --- gr-qtgui/lib/qtgui_time_sink_c.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gr-qtgui/lib/qtgui_time_sink_c.cc') diff --git a/gr-qtgui/lib/qtgui_time_sink_c.cc b/gr-qtgui/lib/qtgui_time_sink_c.cc index 1cd391893..e57ef011a 100644 --- a/gr-qtgui/lib/qtgui_time_sink_c.cc +++ b/gr-qtgui/lib/qtgui_time_sink_c.cc @@ -130,6 +130,12 @@ qtgui_time_sink_c::set_update_time(double t) d_main_gui->SetUpdateTime(d_update_time); } +void +qtgui_time_sink_c::set_title(int which, const std::string &title) +{ + d_main_gui->SetTitle(which, title.c_str()); +} + int qtgui_time_sink_c::general_work (int noutput_items, gr_vector_int &ninput_items, -- cgit From 11de76b9214a59930ac8d8c031880b5bd293973d Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 24 Apr 2011 01:47:05 -0400 Subject: gr-qtgui: adding function and slot to set a time display curve's color. --- gr-qtgui/lib/qtgui_time_sink_c.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gr-qtgui/lib/qtgui_time_sink_c.cc') diff --git a/gr-qtgui/lib/qtgui_time_sink_c.cc b/gr-qtgui/lib/qtgui_time_sink_c.cc index e57ef011a..a1f0130ba 100644 --- a/gr-qtgui/lib/qtgui_time_sink_c.cc +++ b/gr-qtgui/lib/qtgui_time_sink_c.cc @@ -136,6 +136,12 @@ qtgui_time_sink_c::set_title(int which, const std::string &title) d_main_gui->SetTitle(which, title.c_str()); } +void +qtgui_time_sink_c::set_color(int which, const std::string &color) +{ + d_main_gui->SetColor(which, color.c_str()); +} + int qtgui_time_sink_c::general_work (int noutput_items, gr_vector_int &ninput_items, -- cgit From 83c1463ef9aa550d8c44cd259cf14dea433e1973 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 24 Apr 2011 01:59:10 -0400 Subject: gr-qtgui: making (somewhat more) consistent case for function names. --- gr-qtgui/lib/qtgui_time_sink_c.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'gr-qtgui/lib/qtgui_time_sink_c.cc') diff --git a/gr-qtgui/lib/qtgui_time_sink_c.cc b/gr-qtgui/lib/qtgui_time_sink_c.cc index a1f0130ba..c011e8297 100644 --- a/gr-qtgui/lib/qtgui_time_sink_c.cc +++ b/gr-qtgui/lib/qtgui_time_sink_c.cc @@ -120,26 +120,26 @@ qtgui_time_sink_c::pyqwidget() void qtgui_time_sink_c::set_time_domain_axis(double min, double max) { - d_main_gui->SetTimeDomainAxis(min, max); + d_main_gui->setTimeDomainAxis(min, max); } void qtgui_time_sink_c::set_update_time(double t) { d_update_time = t; - d_main_gui->SetUpdateTime(d_update_time); + d_main_gui->setUpdateTime(d_update_time); } void qtgui_time_sink_c::set_title(int which, const std::string &title) { - d_main_gui->SetTitle(which, title.c_str()); + d_main_gui->setTitle(which, title.c_str()); } void qtgui_time_sink_c::set_color(int which, const std::string &color) { - d_main_gui->SetColor(which, color.c_str()); + d_main_gui->setColor(which, color.c_str()); } int -- cgit From f11a20190f36d3f7864f932118d157425e988d0a Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 24 Apr 2011 02:45:38 -0400 Subject: gr-qtgui: Adding float interface to qtgui_time_sink and example program. --- gr-qtgui/lib/qtgui_time_sink_c.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'gr-qtgui/lib/qtgui_time_sink_c.cc') diff --git a/gr-qtgui/lib/qtgui_time_sink_c.cc b/gr-qtgui/lib/qtgui_time_sink_c.cc index c011e8297..f3bc168b2 100644 --- a/gr-qtgui/lib/qtgui_time_sink_c.cc +++ b/gr-qtgui/lib/qtgui_time_sink_c.cc @@ -94,6 +94,7 @@ qtgui_time_sink_c::initialize() // initialize update time to 10 times a second set_update_time(0.1); + d_last_time = {0,0}; } -- cgit