[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r4562 - gnuradio/branches/developers/n4hy/qt/gr-qtgui/
From: |
n4hy |
Subject: |
[Commit-gnuradio] r4562 - gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib |
Date: |
Wed, 21 Feb 2007 13:28:30 -0700 (MST) |
Author: n4hy
Date: 2007-02-21 13:28:29 -0700 (Wed, 21 Feb 2007)
New Revision: 4562
Modified:
gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/Makefile.am
gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/fftdisplay.cc
gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/fftdisplay.h
gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/qt_examples.cc
Log:
Qt: fft display works - needs some minor multithreaded cleanups for the
qt_examples file
Modified: gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/Makefile.am
===================================================================
--- gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/Makefile.am
2007-02-21 19:28:13 UTC (rev 4561)
+++ gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/Makefile.am
2007-02-21 20:28:29 UTC (rev 4562)
@@ -52,7 +52,9 @@
$(qt_examples_MOC)
qt_examples_LDADD = $(QWT_LIBS) $(QT_LIBS)
-qt_examples_LDFLAGS = $(QT_CFLAGS) $(QWT_CFLAGS)
+qt_examples_LDFLAGS = $(QT_CFLAGS) $(QWT_CFLAGS) $(GNURADIO_CORE_LIBS)
MOSTLYCLEANFILES = \
- *~
+ *~
+
+CLEANFILES = $(filter moc_%.cc, $(qt_examples_SOURCES))
Modified: gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/fftdisplay.cc
===================================================================
--- gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/fftdisplay.cc
2007-02-21 19:28:13 UTC (rev 4561)
+++ gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/fftdisplay.cc
2007-02-21 20:28:29 UTC (rev 4562)
@@ -3,21 +3,39 @@
#include <qwt_painter.h>
#include <qwt_plot_canvas.h>
+#include <qwt_plot_curve.h>
+#include <qwt_scale_engine.h>
#include <qapplication.h>
#include <fftdisplay.h>
const int fft_display_event::EVENT_TYPE_ID = QEvent::User+100;
-fft_display_event::fft_display_event():QCustomEvent(fft_display_event::EVENT_TYPE_ID){
-
+fft_display_event::fft_display_event( std::vector<gr_complex>* fft_data, const
float start_frequency, const float
stop_frequency):QCustomEvent(fft_display_event::EVENT_TYPE_ID){
+ d_fft_data.resize(fft_data->size());
+ for(unsigned int i = 0; i < fft_data->size(); i++){
+ d_fft_data[i] = fft_data->operator[](i);
+ }
+ d_start_frequency = start_frequency;
+ d_stop_frequency = stop_frequency;
}
fft_display_event::~fft_display_event(){
}
+const std::vector<gr_complex>& fft_display_event::get_fft_data() const{
+ return d_fft_data;
+}
-fft_display::fft_display(const unsigned int fftSize, QWidget* parent):
+float fft_display_event::get_start_frequency()const{
+ return d_start_frequency;
+}
+
+float fft_display_event::get_stop_frequency()const{
+ return d_stop_frequency;
+}
+
+fft_display::fft_display(const unsigned int fft_size, QWidget* parent):
QwtPlot(parent)
{
// Disable polygon clipping
@@ -27,50 +45,90 @@
canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false);
- d_plot_data.resize(fftSize+1);
- for( unsigned int i = 0; i < fftSize+1; i++){
- d_plot_data[i] = 0.0;
+ canvas()->setPaletteBackgroundColor(QColor("white"));
+
+ d_fft_bin_size = fft_size;
+ if(d_fft_bin_size < 1){
+ d_fft_bin_size = 1;
}
-
+
d_start_frequency = 0.0;
d_stop_frequency = 4000.0;
+ d_fft_data = new std::vector<gr_complex>(d_fft_bin_size);
+ d_plot_data = new double[d_fft_bin_size];
+ d_x_data = new double[d_fft_bin_size];
+ for( unsigned int i = 0; i < d_fft_bin_size; i++){
+ d_fft_data->operator[](i) = gr_complex(static_cast<float>(i),
0.0);
+ d_x_data[i] = d_start_frequency +
((d_stop_frequency-d_start_frequency) /
static_cast<float>(d_fft_bin_size)*static_cast<float>(i));
+ d_plot_data[i] = 1.0;
+ }
+
+ // Set the Appropriate Axis Scale Engine
+#warning Pass the axis info as necessary...
+ if(true){
+ setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
+ }
+ else{
+ setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10ScaleEngine);
+ }
+
+ QwtPlotCurve* fft_plot_curve = new QwtPlotCurve("FFT Spectrum");
+ fft_plot_curve->attach(this);
+ fft_plot_curve->setPen(QPen(Qt::blue));
+ fft_plot_curve->setRawData(d_x_data, d_plot_data, d_fft_bin_size);
+
setTitle("Spectral Display");
}
fft_display::~fft_display(){
+ /* The Qwt objects are destroyed by Qt when their parent is destroyed */
+
+ delete[] d_plot_data;
+ delete[] d_x_data;
+ delete d_fft_data;
}
void fft_display::set_data(const std::vector<gr_complex>& input_data){
- unsigned int min_points = d_plot_data.size();
+ unsigned int min_points = d_fft_data->size();
if(min_points < input_data.size()){
min_points = input_data.size();
}
+ if(min_points > d_fft_bin_size){
+ min_points = d_fft_bin_size;
+ }
for(unsigned int point = 0; point < min_points; point++){
- d_plot_data[point] = input_data[point];
+ d_fft_data->operator[](point) = input_data[point];
}
}
void fft_display::update_display(){
// Tell the event loop to display the new data - the event loop handles
deleting this object
- qApp->postEvent(this, new fft_display_event());
+ qApp->postEvent(this, new fft_display_event(d_fft_data,
d_start_frequency, d_stop_frequency));
}
void fft_display::customEvent(QCustomEvent* e){
if(e->type() == fft_display_event::EVENT_TYPE_ID){
+ fft_display_event* fft_display_event_ptr =
(fft_display_event*)e;
// Write out the FFT data to the display here
- printf("HEY GOT THE EVENT\n");
+ gr_complex data_value;
+ for(unsigned int number = 0; number <
fft_display_event_ptr->get_fft_data().size(); number++){
+ data_value =
fft_display_event_ptr->get_fft_data()[number];
+ d_plot_data[number] = data_value.real();
+#warning Add code here for handling magnitude, scaling, etc...
+
+ d_x_data[number] = d_start_frequency +
((d_stop_frequency-d_start_frequency) /
static_cast<float>(d_fft_bin_size)*static_cast<float>(number));
+ }
+
// Axis
setAxisTitle(QwtPlot::xBottom, "Frequency (Hz)");
- setAxisScale(QwtPlot::xBottom, get_start_frequency(),
get_stop_frequency());
+ setAxisScale(QwtPlot::xBottom,
fft_display_event_ptr->get_start_frequency(),
fft_display_event_ptr->get_stop_frequency());
setAxisTitle(QwtPlot::yLeft, "Values");
- setAxisScale(QwtPlot::yLeft, -1.5, 1.5);
-
replot();
}
}
@@ -91,5 +149,9 @@
return d_stop_frequency;
}
+unsigned int fft_display::get_fft_bin_size()const{
+ return d_fft_bin_size;
+}
+
#endif /* FFT_DISPLAY_CC */
Modified: gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/fftdisplay.h
===================================================================
--- gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/fftdisplay.h
2007-02-21 19:28:13 UTC (rev 4561)
+++ gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/fftdisplay.h
2007-02-21 20:28:29 UTC (rev 4562)
@@ -11,14 +11,20 @@
class fft_display_event:public QCustomEvent{
public:
- fft_display_event();
+ fft_display_event(std::vector<gr_complex>*, const float, const float);
~fft_display_event();
+ const std::vector<gr_complex>& get_fft_data()const;
+ float get_start_frequency()const;
+ float get_stop_frequency()const;
+
static const int EVENT_TYPE_ID;
protected:
private:
-
+ std::vector<gr_complex> d_fft_data;
+ float d_start_frequency;
+ float d_stop_frequency;
};
class fft_display:public QwtPlot{
@@ -35,6 +41,8 @@
void set_stop_frequency(const float);
float get_stop_frequency()const;
+ unsigned int get_fft_bin_size()const;
+
public slots:
virtual void set_data( const std::vector<gr_complex>& );
virtual void update_display();
@@ -42,7 +50,9 @@
protected:
private:
- std::vector<gr_complex> d_plot_data;
+ std::vector<gr_complex>* d_fft_data;
+ double* d_plot_data;
+ double* d_x_data;
unsigned int d_fft_bin_size;
float d_start_frequency;
float d_stop_frequency;
Modified: gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/qt_examples.cc
===================================================================
--- gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/qt_examples.cc
2007-02-21 19:28:13 UTC (rev 4561)
+++ gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib/qt_examples.cc
2007-02-21 20:28:29 UTC (rev 4562)
@@ -1,27 +1,77 @@
#include <stdio.h>
#include <unistd.h>
+#include <iostream>
+#include <fstream>
+
#include <qapplication.h>
+#include <omnithread.h>
#include <vector>
#include <fftdisplay.h>
+#warning Must make this threadsafe
+static bool g_exit_flag = false;
+
+void read_function(void* ptr){
+
+ fft_display* fftDisplay = (fft_display*)ptr;
+
+ std::vector<gr_complex> fftData(fftDisplay->get_fft_bin_size());
+ for(unsigned int number = 0; number < fftData.size(); number++){
+ fftData[number] = gr_complex(static_cast<float>(number),
static_cast<float>(number));
+ }
+
+ float* readBuffer = new float[fftDisplay->get_fft_bin_size()*2];
+ int amntRead = 0;
+
+ fftDisplay->set_data(fftData);
+
+ while(!g_exit_flag){
+ // Read in the data here
+ sched_yield();
+ std::cin.read((char*)readBuffer,
fftDisplay->get_fft_bin_size()*sizeof(gr_complex));
+ amntRead = std::cin.gcount();
+
+ if(amntRead !=
static_cast<int>(fftDisplay->get_fft_bin_size()*sizeof(gr_complex))){
+ fprintf(stderr, "Invalid Read Amount from stdin -
closing program\n");
+ qApp->quit();
+ g_exit_flag = true;
+ }
+ else{
+ for(unsigned int number = 0; number < fftData.size();
number++){
+ fftData[number] =
gr_complex(readBuffer[2*number], readBuffer[(2*number)+1]);
+ }
+
+ fftDisplay->set_data(fftData);
+
+ fftDisplay->update_display();
+
+ qApp->wakeUpGuiThread();
+ }
+ }
+
+ delete[] readBuffer;
+}
+
int main (int argc, char* argv[]){
extern char* optarg;
extern int optind, optopt;
float start_frequency = 0.0;
float stop_frequency = 4000.0;
int c;
+ unsigned int fft_bin_size = 1024;
- const unsigned int FFT_SIZE = 1024;
-
- while ((c = getopt(argc, argv, "s:p:")) != -1){
+ while ((c = getopt(argc, argv, "s:p:b:")) != -1){
switch(c){
case 's': start_frequency = strtod(optarg, NULL); break;
case 'p': stop_frequency = strtod(optarg, NULL); break;
+ case 'b': fft_bin_size = (unsigned int)(atoi(optarg)); break;
case ':': /* -s or -p w/o operand */
fprintf(stderr, "Option -%c requires an arguement\n", optopt);
break;
- case '?': fprintf(stderr, "Unrecognized option: -%c\n",
optopt); exit(-1); break;
+ case '?': fprintf(stderr, "Unrecognized option: -%c\n", optopt);
+ fprintf(stderr, "Valid Arguements\n -s <start
frequency>\n -p <stop frequency> -b <fft_bin_size> - number of fft samples per
display\n");
+ exit(-1); break;
}
}
@@ -34,8 +84,7 @@
// Create the QApplication - this MUST be done before ANY QObjects are
created
QApplication* qApp = new QApplication(argc, argv);
- // Set up the thread to read the data from stdin
- fft_display* fftDisplay = new fft_display(FFT_SIZE); // No Parent
Specified
+ fft_display* fftDisplay = new fft_display(fft_bin_size); // No Parent
Specified
// Resize the Display
fftDisplay->resize(640,240);
@@ -44,24 +93,26 @@
fftDisplay->set_start_frequency(start_frequency);
fftDisplay->set_stop_frequency(stop_frequency);
- std::vector<gr_complex> fftData(FFT_SIZE);
- for(unsigned int number = 0; number < fftData.size(); number++){
- fftData[number] = gr_complex(static_cast<float>(number),
static_cast<float>(number));
- }
+ g_exit_flag = false;
+ omni_thread* thread_ptr = new omni_thread(&read_function,
(void*)fftDisplay);
- fftDisplay->set_data(fftData);
+ // Set up the thread to read the data from stdin
+ thread_ptr->start();
+ sched_yield();
+ // Make the closing of the last window call the quit()
+ QObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()));
+
// finally, refresh the plot
fftDisplay->update_display();
fftDisplay->show();
- // Make the closing of the last window call the quit()
- QObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()));
-
// Start the Event Thread
qApp->exec();
// No QObjects should be deleted once the event thread exits...
+ g_exit_flag = true;
+
delete fftDisplay;
// Destroy the Event Thread
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r4562 - gnuradio/branches/developers/n4hy/qt/gr-qtgui/src/lib,
n4hy <=