commit-gnuradio
[Top][All Lists]
Advanced

[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





reply via email to

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