From 322e065b19c922e2a9cc1710876e32d100453181 Mon Sep 17 00:00:00 2001 From: trondeau Date: Wed, 15 Apr 2009 03:49:04 +0000 Subject: [PATCH] Merging qtdevel2 branch -r10565:10849. This adds a lot of fixes and capabilities to the qtgui package. Most importantly, it allows interaction between PyQt and the C++ Qt routines in the gnuradio library. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10850 221aa14e-8319-0410-a670-987f0aec2ac5 --- config/grc_gr_qtgui.m4 | 8 + gr-qtgui/src/lib/ConstellationDisplayPlot.cc | 7 +- gr-qtgui/src/lib/FrequencyDisplayPlot.cc | 139 +++--- gr-qtgui/src/lib/FrequencyDisplayPlot.h | 9 +- gr-qtgui/src/lib/Makefile.am | 2 +- gr-qtgui/src/lib/SpectrumGUIClass.cc | 174 ++++++-- gr-qtgui/src/lib/SpectrumGUIClass.h | 19 +- gr-qtgui/src/lib/Waterfall3DDisplayPlot.cc | 14 +- gr-qtgui/src/lib/Waterfall3DDisplayPlot.h | 4 +- gr-qtgui/src/lib/WaterfallDisplayPlot.cc | 47 ++- gr-qtgui/src/lib/WaterfallDisplayPlot.h | 9 +- gr-qtgui/src/lib/qtgui.i | 66 ++- gr-qtgui/src/lib/qtgui_sink_c.cc | 158 ++++--- gr-qtgui/src/lib/qtgui_sink_c.h | 44 +- gr-qtgui/src/lib/qtgui_sink_f.cc | 164 ++++++-- gr-qtgui/src/lib/qtgui_sink_f.h | 57 ++- gr-qtgui/src/lib/spectrumUpdateEvents.cc | 106 +++-- gr-qtgui/src/lib/spectrumdisplayform.cc | 421 +++++++++++++------ gr-qtgui/src/lib/spectrumdisplayform.h | 25 +- gr-qtgui/src/lib/spectrumdisplayform.ui | 6 +- gr-qtgui/src/python/Makefile.am | 11 +- gr-qtgui/src/python/pyqt_example.py | 144 +++++++ gr-qtgui/src/python/pyqt_example_f.py | 143 +++++++ gr-qtgui/src/python/qt_digital.py | 134 +++++- gr-qtgui/src/python/qttest_c.py | 37 -- gr-qtgui/src/python/qttest_f.py | 29 -- gr-qtgui/src/python/usrp2_display.py | 231 ++++++++++ gr-qtgui/src/python/usrp_display.py | 208 +++++++++ 28 files changed, 1908 insertions(+), 508 deletions(-) create mode 100755 gr-qtgui/src/python/pyqt_example.py create mode 100755 gr-qtgui/src/python/pyqt_example_f.py delete mode 100755 gr-qtgui/src/python/qttest_c.py delete mode 100755 gr-qtgui/src/python/qttest_f.py create mode 100755 gr-qtgui/src/python/usrp2_display.py create mode 100755 gr-qtgui/src/python/usrp_display.py diff --git a/config/grc_gr_qtgui.m4 b/config/grc_gr_qtgui.m4 index a6261290..d9700776 100644 --- a/config/grc_gr_qtgui.m4 +++ b/config/grc_gr_qtgui.m4 @@ -28,6 +28,14 @@ AC_DEFUN([GRC_GR_QTGUI],[ dnl yes : if the --enable code passed muster and all dependencies are met dnl no : otherwise + PYTHON_CHECK_MODULE([PyQt4.QtCore], [PyQt4 for Qt4], \ + [passed=yes], [passed=no], \ + [PyQt4.QtCore.PYQT_VERSION >= 260000]) + + # Enable this if we want to test for PyQwt, too + #PYTHON_CHECK_MODULE([PyQt4.Qwt5], [PyQwt5 for Qt4], \ + # [passed=yes], [passed=no], \ + # [PyQt4.Qwt5.QWT_VERSION >= 327000]) # Check for: # QtOpenGL diff --git a/gr-qtgui/src/lib/ConstellationDisplayPlot.cc b/gr-qtgui/src/lib/ConstellationDisplayPlot.cc index c422c8f5..6f423d9a 100644 --- a/gr-qtgui/src/lib/ConstellationDisplayPlot.cc +++ b/gr-qtgui/src/lib/ConstellationDisplayPlot.cc @@ -100,11 +100,8 @@ ConstellationDisplayPlot::ConstellationDisplayPlot(QWidget* parent):QwtPlot(pare _zoomer->setRubberBandPen(c); _zoomer->setTrackerPen(c); - QwtLegend* legendDisplay = new QwtLegend(this); - legendDisplay->setItemMode(QwtLegend::CheckableItem); - insertLegend(legendDisplay); - - connect(this, SIGNAL( legendChecked(QwtPlotItem *, bool ) ), this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) )); + connect(this, SIGNAL( legendChecked(QwtPlotItem *, bool ) ), + this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) )); } ConstellationDisplayPlot::~ConstellationDisplayPlot(){ diff --git a/gr-qtgui/src/lib/FrequencyDisplayPlot.cc b/gr-qtgui/src/lib/FrequencyDisplayPlot.cc index 9fb9253b..4f9bfdd9 100644 --- a/gr-qtgui/src/lib/FrequencyDisplayPlot.cc +++ b/gr-qtgui/src/lib/FrequencyDisplayPlot.cc @@ -8,18 +8,22 @@ class FreqPrecisionClass { public: - FreqPrecisionClass(const int freqPrecision){ + FreqPrecisionClass(const int freqPrecision) + { _frequencyPrecision = freqPrecision; } - virtual ~FreqPrecisionClass(){ + virtual ~FreqPrecisionClass() + { } - virtual unsigned int GetFrequencyPrecision()const{ + virtual unsigned int GetFrequencyPrecision() const + { return _frequencyPrecision; } - virtual void SetFrequencyPrecision(const unsigned int newPrecision){ + virtual void SetFrequencyPrecision(const unsigned int newPrecision) + { _frequencyPrecision = newPrecision; } protected: @@ -29,17 +33,20 @@ private: }; -class FreqDisplayScaleDraw: public QwtScaleDraw, public FreqPrecisionClass{ +class FreqDisplayScaleDraw: public QwtScaleDraw, public FreqPrecisionClass +{ public: - FreqDisplayScaleDraw(const unsigned int precision):QwtScaleDraw(), FreqPrecisionClass(precision){ - + FreqDisplayScaleDraw(const unsigned int precision) + : QwtScaleDraw(), FreqPrecisionClass(precision) + { } - virtual ~FreqDisplayScaleDraw(){ - + virtual ~FreqDisplayScaleDraw() + { } - virtual QwtText label(double value)const{ + virtual QwtText label(double value) const + { return QString("%1").arg(value, 0, 'f', GetFrequencyPrecision()); } @@ -52,7 +59,8 @@ private: class FreqDisplayZoomer: public QwtPlotZoomer, public FreqPrecisionClass { public: - FreqDisplayZoomer(QwtPlotCanvas* canvas, const unsigned int freqPrecision):QwtPlotZoomer(canvas),FreqPrecisionClass(freqPrecision) + FreqDisplayZoomer(QwtPlotCanvas* canvas, const unsigned int freqPrecision) + : QwtPlotZoomer(canvas),FreqPrecisionClass(freqPrecision) { setTrackerMode(QwtPicker::AlwaysOn); } @@ -74,7 +82,9 @@ protected: } }; -FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent):QwtPlot(parent){ +FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent) + : QwtPlot(parent) +{ _startFrequency = 0; _stopFrequency = 4000; @@ -199,10 +209,10 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent):QwtPlot(parent){ const QColor c(Qt::darkRed); _zoomer->setRubberBandPen(c); _zoomer->setTrackerPen(c); - } -FrequencyDisplayPlot::~FrequencyDisplayPlot(){ +FrequencyDisplayPlot::~FrequencyDisplayPlot() +{ delete[] _dataPoints; delete[] _maxFFTPoints; delete[] _minFFTPoints; @@ -212,49 +222,37 @@ FrequencyDisplayPlot::~FrequencyDisplayPlot(){ // _zoomer and _panner deleted when parent deleted } -void FrequencyDisplayPlot::SetFrequencyRange(const double constStartFreq, const double constStopFreq, const double centerFrequency, const bool useCenterFrequencyFlag){ - double startFreq = constStartFreq; - double stopFreq = constStopFreq; +void +FrequencyDisplayPlot::SetFrequencyRange(const double constStartFreq, + const double constStopFreq, + const double constCenterFreq, + const bool useCenterFrequencyFlag, + const double units, const std::string &strunits) +{ + double startFreq = constStartFreq / units; + double stopFreq = constStopFreq / units; + double centerFreq = constCenterFreq / units; _useCenterFrequencyFlag = useCenterFrequencyFlag; if(_useCenterFrequencyFlag){ - startFreq = (startFreq + centerFrequency) / 1000.0; - stopFreq = (stopFreq + centerFrequency) / 1000.0; - } - - if((stopFreq > 0) && (stopFreq > startFreq)){ - _startFrequency = startFreq; - _stopFrequency = stopFreq; - _resetXAxisPoints(); - - // Load up the new base zoom settings - QwtDoubleRect newSize = _zoomer->zoomBase(); - newSize.setLeft(_startFrequency); - newSize.setWidth(_stopFrequency-_startFrequency); - _zoomer->setZoomBase(newSize); - - // Zooms back to the base and clears any other zoom levels - _zoomer->zoom(0); - - setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency); + startFreq = (startFreq + centerFreq); + stopFreq = (stopFreq + centerFreq); } - if(useCenterFrequencyFlag){ - setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(3)); - setAxisTitle(QwtPlot::xBottom, "RF Frequency (kHz)"); - ((FreqDisplayZoomer*)_zoomer)->SetFrequencyPrecision(3); - } - else{ - setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(0)); - setAxisTitle(QwtPlot::xBottom, "Frequency (Hz)"); - ((FreqDisplayZoomer*)_zoomer)->SetFrequencyPrecision(0); - } + _startFrequency = startFreq; + _stopFrequency = stopFreq; + _resetXAxisPoints(); + + setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency); + setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(2)); + setAxisTitle(QwtPlot::xBottom, QString("Frequency (%1)").arg(strunits.c_str())); + ((FreqDisplayZoomer*)_zoomer)->SetFrequencyPrecision(2); // Load up the new base zoom settings QwtDoubleRect newSize = _zoomer->zoomBase(); newSize.setLeft(_startFrequency); - newSize.setWidth(_stopFrequency-_startFrequency); + newSize.setWidth(_stopFrequency-_startFrequency); _zoomer->setZoomBase(newSize); // Zooms back to the base and clears any other zoom levels @@ -262,16 +260,21 @@ void FrequencyDisplayPlot::SetFrequencyRange(const double constStartFreq, const } -double FrequencyDisplayPlot::GetStartFrequency()const{ +double +FrequencyDisplayPlot::GetStartFrequency() const +{ return _startFrequency; } -double FrequencyDisplayPlot::GetStopFrequency()const{ +double +FrequencyDisplayPlot::GetStopFrequency() const +{ return _stopFrequency; } -void FrequencyDisplayPlot::replot(){ - +void +FrequencyDisplayPlot::replot() +{ const timespec startTime = get_highres_clock(); _markerNoiseFloorAmplitude->setYValue(_noiseFloorAmplitude); @@ -296,7 +299,11 @@ void FrequencyDisplayPlot::replot(){ } } -void FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDataPoints, const double noiseFloorAmplitude, const double peakFrequency, const double peakAmplitude){ +void +FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDataPoints, + const double noiseFloorAmplitude, const double peakFrequency, + const double peakAmplitude) +{ if(numDataPoints > 0){ if(numDataPoints != _numPoints){ @@ -345,27 +352,37 @@ void FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t n } } -void FrequencyDisplayPlot::ClearMaxData(){ +void +FrequencyDisplayPlot::ClearMaxData() +{ for(int64_t number = 0; number < _numPoints; number++){ _maxFFTPoints[number] = -280.0; } } -void FrequencyDisplayPlot::ClearMinData(){ +void +FrequencyDisplayPlot::ClearMinData() +{ for(int64_t number = 0; number < _numPoints; number++){ _minFFTPoints[number] = 200.0; } } -void FrequencyDisplayPlot::SetMaxFFTVisible(const bool visibleFlag){ +void +FrequencyDisplayPlot::SetMaxFFTVisible(const bool visibleFlag) +{ _max_fft_plot_curve->setVisible(visibleFlag); } -void FrequencyDisplayPlot::SetMinFFTVisible(const bool visibleFlag){ +void +FrequencyDisplayPlot::SetMinFFTVisible(const bool visibleFlag) +{ _min_fft_plot_curve->setVisible(visibleFlag); } -void FrequencyDisplayPlot::_resetXAxisPoints(){ +void +FrequencyDisplayPlot::_resetXAxisPoints() +{ double fft_bin_size = (_stopFrequency-_startFrequency) / static_cast(_numPoints); double freqValue = _startFrequency; for(int64_t loc = 0; loc < _numPoints; loc++){ @@ -374,11 +391,15 @@ void FrequencyDisplayPlot::_resetXAxisPoints(){ } } -void FrequencyDisplayPlot::SetLowerIntensityLevel(const double lowerIntensityLevel){ +void +FrequencyDisplayPlot::SetLowerIntensityLevel(const double lowerIntensityLevel) +{ _lower_intensity_marker->setYValue( lowerIntensityLevel ); } -void FrequencyDisplayPlot::SetUpperIntensityLevel(const double upperIntensityLevel){ +void +FrequencyDisplayPlot::SetUpperIntensityLevel(const double upperIntensityLevel) +{ _upper_intensity_marker->setYValue( upperIntensityLevel ); } diff --git a/gr-qtgui/src/lib/FrequencyDisplayPlot.h b/gr-qtgui/src/lib/FrequencyDisplayPlot.h index fb647d96..061ef6ef 100644 --- a/gr-qtgui/src/lib/FrequencyDisplayPlot.h +++ b/gr-qtgui/src/lib/FrequencyDisplayPlot.h @@ -20,11 +20,16 @@ public: FrequencyDisplayPlot(QWidget*); virtual ~FrequencyDisplayPlot(); - void SetFrequencyRange(const double, const double, const double, const bool); + void SetFrequencyRange(const double, const double, + const double, const bool, + const double units=1000.0, + const std::string &strunits = "kHz"); double GetStartFrequency()const; double GetStopFrequency()const; - void PlotNewData(const double* dataPoints, const int64_t numDataPoints, const double noiseFloorAmplitude, const double peakFrequency, const double peakAmplitude); + void PlotNewData(const double* dataPoints, const int64_t numDataPoints, + const double noiseFloorAmplitude, const double peakFrequency, + const double peakAmplitude); void ClearMaxData(); void ClearMinData(); diff --git a/gr-qtgui/src/lib/Makefile.am b/gr-qtgui/src/lib/Makefile.am index eee58990..3c05d28f 100644 --- a/gr-qtgui/src/lib/Makefile.am +++ b/gr-qtgui/src/lib/Makefile.am @@ -108,7 +108,7 @@ TOP_SWIG_IFILES = \ # This ends up at: # ${prefix}/lib/python${python_version}/site-packages/gnuradio qtgui_pythondir_category = \ - gnuradio + gnuradio/qtgui # additional libraries for linking with the SWIG-generated library qtgui_la_swig_libadd = \ diff --git a/gr-qtgui/src/lib/SpectrumGUIClass.cc b/gr-qtgui/src/lib/SpectrumGUIClass.cc index f9988d8f..06450845 100644 --- a/gr-qtgui/src/lib/SpectrumGUIClass.cc +++ b/gr-qtgui/src/lib/SpectrumGUIClass.cc @@ -9,8 +9,11 @@ const long SpectrumGUIClass::MAX_FFT_SIZE; const long SpectrumGUIClass::MIN_FFT_SIZE; -SpectrumGUIClass::SpectrumGUIClass(const uint64_t maxDataSize, const uint64_t fftSize, - const double newStartFrequency, const double newStopFrequency){ +SpectrumGUIClass::SpectrumGUIClass(const uint64_t maxDataSize, + const uint64_t fftSize, + const double newStartFrequency, + const double newStopFrequency) +{ _dataPoints = maxDataSize; if(_dataPoints < 2){ _dataPoints = 2; @@ -40,7 +43,8 @@ SpectrumGUIClass::SpectrumGUIClass(const uint64_t maxDataSize, const uint64_t ff _powerValue = 1; } -SpectrumGUIClass::~SpectrumGUIClass(){ +SpectrumGUIClass::~SpectrumGUIClass() +{ if(GetWindowOpenFlag()){ delete _spectrumDisplayForm; } @@ -54,7 +58,12 @@ SpectrumGUIClass::~SpectrumGUIClass(){ //delete _windowStateLock; } -void SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent){ +void +SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent, + const bool frequency, const bool waterfall, + const bool waterfall3d, const bool time, + const bool constellation) +{ //_windowStateLock->Lock(); if(!_windowOpennedFlag){ @@ -73,6 +82,13 @@ void SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent){ // Called from the Event Thread _spectrumDisplayForm = new SpectrumDisplayForm(parent); + + // Toggle Windows on/off + _spectrumDisplayForm->ToggleTabFrequency(frequency); + _spectrumDisplayForm->ToggleTabWaterfall(waterfall); + _spectrumDisplayForm->ToggleTabWaterfall3D(waterfall3d); + _spectrumDisplayForm->ToggleTabTime(time); + _spectrumDisplayForm->ToggleTabConstellation(constellation); _windowOpennedFlag = true; @@ -86,9 +102,8 @@ void SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent){ SetDisplayTitle(_title); Reset(); - qApp->postEvent(_spectrumDisplayForm, new QEvent(QEvent::Type(QEvent::User+3))); - - _spectrumDisplayForm->show(); + qApp->postEvent(_spectrumDisplayForm, + new QEvent(QEvent::Type(QEvent::User+3))); qApp->processEvents(); @@ -101,11 +116,14 @@ void SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent){ qApp->processEvents(); } -void SpectrumGUIClass::Reset(){ - if(GetWindowOpenFlag()){ - qApp->postEvent(_spectrumDisplayForm, new SpectrumFrequencyRangeEvent(_centerFrequency, - _startFrequency, - _stopFrequency)); +void +SpectrumGUIClass::Reset() +{ + if(GetWindowOpenFlag()) { + qApp->postEvent(_spectrumDisplayForm, + new SpectrumFrequencyRangeEvent(_centerFrequency, + _startFrequency, + _stopFrequency)); qApp->postEvent(_spectrumDisplayForm, new SpectrumWindowResetEvent()); } _droppedEntriesCount = 0; @@ -113,16 +131,20 @@ void SpectrumGUIClass::Reset(){ // ResetPendingGUIUpdateEvents(); } -void SpectrumGUIClass::SetDisplayTitle(const std::string newString){ +void +SpectrumGUIClass::SetDisplayTitle(const std::string newString) +{ _title.assign(newString); if(GetWindowOpenFlag()){ - qApp->postEvent(_spectrumDisplayForm, new SpectrumWindowCaptionEvent(_title.c_str())); + qApp->postEvent(_spectrumDisplayForm, + new SpectrumWindowCaptionEvent(_title.c_str())); } - } -bool SpectrumGUIClass::GetWindowOpenFlag(){ +bool +SpectrumGUIClass::GetWindowOpenFlag() +{ bool returnFlag = false; //_windowStateLock->Lock(); returnFlag = _windowOpennedFlag; @@ -131,21 +153,33 @@ bool SpectrumGUIClass::GetWindowOpenFlag(){ } -void SpectrumGUIClass::SetWindowOpenFlag(const bool newFlag){ +void +SpectrumGUIClass::SetWindowOpenFlag(const bool newFlag) +{ //_windowStateLock->Lock(); _windowOpennedFlag = newFlag; //_windowStateLock->Unlock(); } -void SpectrumGUIClass::SetFrequencyRange(const double centerFreq, const double startFreq, const double stopFreq){ +void +SpectrumGUIClass::SetFrequencyRange(const double centerFreq, + const double startFreq, + const double stopFreq) +{ //_windowStateLock->Lock(); _centerFrequency = centerFreq; _startFrequency = startFreq; _stopFrequency = stopFreq; + + _spectrumDisplayForm->SetFrequencyRange(_centerFrequency, + _startFrequency, + _stopFrequency); //_windowStateLock->Unlock(); } -double SpectrumGUIClass::GetStartFrequency()const{ +double +SpectrumGUIClass::GetStartFrequency() const +{ double returnValue = 0.0; //_windowStateLock->Lock(); returnValue = _startFrequency; @@ -153,7 +187,9 @@ double SpectrumGUIClass::GetStartFrequency()const{ return returnValue; } -double SpectrumGUIClass::GetStopFrequency()const{ +double +SpectrumGUIClass::GetStopFrequency() const +{ double returnValue = 0.0; //_windowStateLock->Lock(); returnValue = _stopFrequency; @@ -161,7 +197,9 @@ double SpectrumGUIClass::GetStopFrequency()const{ return returnValue; } -double SpectrumGUIClass::GetCenterFrequency()const{ +double +SpectrumGUIClass::GetCenterFrequency() const +{ double returnValue = 0.0; //_windowStateLock->Lock(); returnValue = _centerFrequency; @@ -170,8 +208,18 @@ double SpectrumGUIClass::GetCenterFrequency()const{ } -void SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag, const std::complex* fftBuffer, const uint64_t inputBufferSize, const float* realTimeDomainData, const uint64_t realTimeDomainDataSize, const float* complexTimeDomainData, const uint64_t complexTimeDomainDataSize, const double timePerFFT, const timespec timestamp, const bool lastOfMultipleFFTUpdateFlag){ - +void +SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag, + const std::complex* fftBuffer, + const uint64_t inputBufferSize, + const float* realTimeDomainData, + const uint64_t realTimeDomainDataSize, + const float* complexTimeDomainData, + const uint64_t complexTimeDomainDataSize, + const double timePerFFT, + const timespec timestamp, + const bool lastOfMultipleFFTUpdateFlag) +{ int64_t bufferSize = inputBufferSize; bool repeatDataFlag = false; if(bufferSize > _dataPoints){ @@ -179,7 +227,7 @@ void SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag, const std::com } int64_t timeDomainBufferSize = 0; - if( updateDisplayFlag){ + if(updateDisplayFlag){ if((fftBuffer != NULL) && (bufferSize > 0)){ memcpy(_fftPoints, fftBuffer, bufferSize * sizeof(std::complex)); } @@ -225,25 +273,36 @@ void SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag, const std::com const timespec currentTime = get_highres_clock(); const timespec lastUpdateGUITime = GetLastGUIUpdateTime(); - if((diff_timespec(currentTime, lastUpdateGUITime) > (4*timePerFFT)) && (GetPendingGUIUpdateEvents() > 0) && !timespec_empty(&lastUpdateGUITime)){ + if((diff_timespec(currentTime, lastUpdateGUITime) > (4*timePerFFT)) && + (GetPendingGUIUpdateEvents() > 0) && !timespec_empty(&lastUpdateGUITime)) { // Do not update the display if too much data is pending to be displayed _droppedEntriesCount++; } else{ // Draw the Data IncrementPendingGUIUpdateEvents(); - qApp->postEvent(_spectrumDisplayForm, new SpectrumUpdateEvent(_fftPoints, bufferSize, _realTimeDomainPoints, _imagTimeDomainPoints, timeDomainBufferSize, timePerFFT, timestamp, repeatDataFlag, lastOfMultipleFFTUpdateFlag, currentTime, _droppedEntriesCount)); + qApp->postEvent(_spectrumDisplayForm, + new SpectrumUpdateEvent(_fftPoints, bufferSize, + _realTimeDomainPoints, + _imagTimeDomainPoints, + timeDomainBufferSize, + timePerFFT, timestamp, + repeatDataFlag, + lastOfMultipleFFTUpdateFlag, + currentTime, + _droppedEntriesCount)); - // Only reset the dropped entries counter if this is not repeat data since repeat data is dropped by the display systems + // Only reset the dropped entries counter if this is not + // repeat data since repeat data is dropped by the display systems if(!repeatDataFlag){ _droppedEntriesCount = 0; } - - //qApp->wakeUpGuiThread(); } } -float SpectrumGUIClass::GetPowerValue()const{ +float +SpectrumGUIClass::GetPowerValue() const +{ float returnValue = 0; //_windowStateLock->Lock(); returnValue = _powerValue; @@ -251,13 +310,17 @@ float SpectrumGUIClass::GetPowerValue()const{ return returnValue; } -void SpectrumGUIClass::SetPowerValue(const float value){ +void +SpectrumGUIClass::SetPowerValue(const float value) +{ //_windowStateLock->Lock(); _powerValue = value; //_windowStateLock->Unlock(); } -int SpectrumGUIClass::GetWindowType()const{ +int +SpectrumGUIClass::GetWindowType() const +{ int returnValue = 0; //_windowStateLock->Lock(); returnValue = _windowType; @@ -265,13 +328,17 @@ int SpectrumGUIClass::GetWindowType()const{ return returnValue; } -void SpectrumGUIClass::SetWindowType(const int newType){ +void +SpectrumGUIClass::SetWindowType(const int newType) +{ //_windowStateLock->Lock(); _windowType = newType; //_windowStateLock->Unlock(); } -int SpectrumGUIClass::GetFFTSize()const{ +int +SpectrumGUIClass::GetFFTSize() const +{ int returnValue = 0; //_windowStateLock->Lock(); returnValue = _fftSize; @@ -279,7 +346,9 @@ int SpectrumGUIClass::GetFFTSize()const{ return returnValue; } -int SpectrumGUIClass::GetFFTSizeIndex()const{ +int +SpectrumGUIClass::GetFFTSizeIndex() const +{ int fftsize = GetFFTSize(); switch(fftsize) { case(1024): return 0; break; @@ -292,13 +361,17 @@ int SpectrumGUIClass::GetFFTSizeIndex()const{ } } -void SpectrumGUIClass::SetFFTSize(const int newSize){ +void +SpectrumGUIClass::SetFFTSize(const int newSize) +{ //_windowStateLock->Lock(); _fftSize = newSize; //_windowStateLock->Unlock(); } -timespec SpectrumGUIClass::GetLastGUIUpdateTime()const{ +timespec +SpectrumGUIClass::GetLastGUIUpdateTime() const +{ timespec returnValue; //_windowStateLock->Lock(); returnValue = _lastGUIUpdateTime; @@ -306,13 +379,17 @@ timespec SpectrumGUIClass::GetLastGUIUpdateTime()const{ return returnValue; } -void SpectrumGUIClass::SetLastGUIUpdateTime(const timespec newTime){ +void +SpectrumGUIClass::SetLastGUIUpdateTime(const timespec newTime) +{ //_windowStateLock->Lock(); _lastGUIUpdateTime = newTime; //_windowStateLock->Unlock(); } -unsigned int SpectrumGUIClass::GetPendingGUIUpdateEvents()const{ +unsigned int +SpectrumGUIClass::GetPendingGUIUpdateEvents() const +{ unsigned int returnValue = 0; //_windowStateLock->Lock(); returnValue = _pendingGUIUpdateEventsCount; @@ -320,13 +397,17 @@ unsigned int SpectrumGUIClass::GetPendingGUIUpdateEvents()const{ return returnValue; } -void SpectrumGUIClass::IncrementPendingGUIUpdateEvents(){ +void +SpectrumGUIClass::IncrementPendingGUIUpdateEvents() +{ //_windowStateLock->Lock(); _pendingGUIUpdateEventsCount++; //_windowStateLock->Unlock(); } -void SpectrumGUIClass::DecrementPendingGUIUpdateEvents(){ +void +SpectrumGUIClass::DecrementPendingGUIUpdateEvents() +{ //_windowStateLock->Lock(); if(_pendingGUIUpdateEventsCount > 0){ _pendingGUIUpdateEventsCount--; @@ -334,11 +415,20 @@ void SpectrumGUIClass::DecrementPendingGUIUpdateEvents(){ //_windowStateLock->Unlock(); } -void SpectrumGUIClass::ResetPendingGUIUpdateEvents(){ +void +SpectrumGUIClass::ResetPendingGUIUpdateEvents() +{ //_windowStateLock->Lock(); _pendingGUIUpdateEventsCount = 0; //_windowStateLock->Unlock(); } +QWidget* +SpectrumGUIClass::qwidget() +{ + return (QWidget*)_spectrumDisplayForm; +} + + #endif /* SPECTRUM_GUI_CLASS_CPP */ diff --git a/gr-qtgui/src/lib/SpectrumGUIClass.h b/gr-qtgui/src/lib/SpectrumGUIClass.h index 4f8fb978..fafae0c6 100644 --- a/gr-qtgui/src/lib/SpectrumGUIClass.h +++ b/gr-qtgui/src/lib/SpectrumGUIClass.h @@ -19,13 +19,18 @@ class SpectrumDisplayForm; #include #include -class SpectrumGUIClass{ +class SpectrumGUIClass +{ public: - SpectrumGUIClass(const uint64_t, const uint64_t, const double, const double); + SpectrumGUIClass(const uint64_t maxDataSize, const uint64_t fftSize, + const double newStartFrequency, const double newStopFrequency); ~SpectrumGUIClass(); void Reset(); - void OpenSpectrumWindow(QWidget*); + void OpenSpectrumWindow(QWidget*, + const bool frequency=true, const bool waterfall=true, + const bool waterfall3d=true, const bool time=true, + const bool constellation=true); void SetDisplayTitle(const std::string); bool GetWindowOpenFlag(); @@ -36,7 +41,11 @@ public: double GetStopFrequency()const; double GetCenterFrequency()const; - void UpdateWindow(const bool, const std::complex*, const uint64_t, const float*, const uint64_t, const float*, const uint64_t, const double, const timespec, const bool); + void UpdateWindow(const bool, const std::complex*, + const uint64_t, const float*, + const uint64_t, const float*, + const uint64_t, const double, + const timespec, const bool); float GetPowerValue()const; void SetPowerValue(const float); @@ -59,6 +68,8 @@ public: static const long MAX_FFT_SIZE = /*1048576*/32768; static const long MIN_FFT_SIZE = 1024; + QWidget* qwidget(); + protected: private: diff --git a/gr-qtgui/src/lib/Waterfall3DDisplayPlot.cc b/gr-qtgui/src/lib/Waterfall3DDisplayPlot.cc index 21011ed6..1b665061 100644 --- a/gr-qtgui/src/lib/Waterfall3DDisplayPlot.cc +++ b/gr-qtgui/src/lib/Waterfall3DDisplayPlot.cc @@ -111,8 +111,18 @@ void Waterfall3DDisplayPlot::Reset(){ _timePerFFT = 1.0; } -void Waterfall3DDisplayPlot::SetFrequencyRange(const double startFreq, const double stopFreq, const double centerFreq, const bool useCenterFrequencyFlag){ - if((stopFreq > 0) && (stopFreq > startFreq)){ +void +Waterfall3DDisplayPlot::SetFrequencyRange(const double constStartFreq, + const double constStopFreq, + const double constCenterFreq, + const bool useCenterFrequencyFlag, + const double units, const std::string &strunits) +{ + double startFreq = constStartFreq / units; + double stopFreq = constStopFreq / units; + double centerFreq = constCenterFreq / units; + + if(stopFreq > startFreq) { _startFrequency = startFreq; _stopFrequency = stopFreq; diff --git a/gr-qtgui/src/lib/Waterfall3DDisplayPlot.h b/gr-qtgui/src/lib/Waterfall3DDisplayPlot.h index dcdbf380..8af5f6b5 100644 --- a/gr-qtgui/src/lib/Waterfall3DDisplayPlot.h +++ b/gr-qtgui/src/lib/Waterfall3DDisplayPlot.h @@ -130,7 +130,9 @@ public: bool loadFromData(double** data, unsigned int columns, unsigned int rows ,double minx, double maxx, double miny, double maxy); - void SetFrequencyRange(const double, const double, const double, const bool); + void SetFrequencyRange(const double, const double, + const double, const bool, + const double units, const std::string &strunits); double GetStartFrequency()const; double GetStopFrequency()const; diff --git a/gr-qtgui/src/lib/WaterfallDisplayPlot.cc b/gr-qtgui/src/lib/WaterfallDisplayPlot.cc index 0f15d95f..ad167f09 100644 --- a/gr-qtgui/src/lib/WaterfallDisplayPlot.cc +++ b/gr-qtgui/src/lib/WaterfallDisplayPlot.cc @@ -182,7 +182,9 @@ const int WaterfallDisplayPlot::INTENSITY_COLOR_MAP_TYPE_BLACK_HOT; const int WaterfallDisplayPlot::INTENSITY_COLOR_MAP_TYPE_INCANDESCENT; const int WaterfallDisplayPlot::INTENSITY_COLOR_MAP_TYPE_USER_DEFINED; -WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent):QwtPlot(parent){ +WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent) + : QwtPlot(parent) +{ _zoomer = NULL; _startFrequency = 0; _stopFrequency = 4000; @@ -253,11 +255,14 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent):QwtPlot(parent){ _UpdateIntensityRangeDisplay(); } -WaterfallDisplayPlot::~WaterfallDisplayPlot(){ +WaterfallDisplayPlot::~WaterfallDisplayPlot() +{ delete _waterfallData; } -void WaterfallDisplayPlot::Reset(){ +void +WaterfallDisplayPlot::Reset() +{ _waterfallData->ResizeData(_startFrequency, _stopFrequency, _numPoints); _waterfallData->Reset(); @@ -270,25 +275,31 @@ void WaterfallDisplayPlot::Reset(){ _zoomer->zoom(0); } -void WaterfallDisplayPlot::SetFrequencyRange(const double startFreq, const double stopFreq, const double centerFreq, const bool useCenterFrequencyFlag){ - if((stopFreq > 0) && (stopFreq > startFreq)){ - _startFrequency = startFreq; - _stopFrequency = stopFreq; +void +WaterfallDisplayPlot::SetFrequencyRange(const double constStartFreq, + const double constStopFreq, + const double constCenterFreq, + const bool useCenterFrequencyFlag, + const double units, const std::string &strunits) +{ + double startFreq = constStartFreq / units; + double stopFreq = constStopFreq / units; + double centerFreq = constCenterFreq / units; + + if(stopFreq > startFreq) { + _startFrequency = 1000*startFreq; + _stopFrequency = 1000*stopFreq; + + setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency); if((axisScaleDraw(QwtPlot::xBottom) != NULL) && (_zoomer != NULL)){ WaterfallFreqDisplayScaleDraw* freqScale = ((WaterfallFreqDisplayScaleDraw*)axisScaleDraw(QwtPlot::xBottom)); freqScale->SetCenterFrequency(centerFreq); ((WaterfallZoomer*)_zoomer)->SetCenterFrequency(centerFreq); - if(useCenterFrequencyFlag){ - freqScale->SetFrequencyPrecision( 3 ); - ((WaterfallZoomer*)_zoomer)->SetFrequencyPrecision( 3 ); - setAxisTitle(QwtPlot::xBottom, "Frequency (kHz)"); - } - else{ - freqScale->SetFrequencyPrecision( 0 ); - ((WaterfallZoomer*)_zoomer)->SetFrequencyPrecision( 0 ); - setAxisTitle(QwtPlot::xBottom, "Frequency (Hz)"); - } + + freqScale->SetFrequencyPrecision( 2 ); + ((WaterfallZoomer*)_zoomer)->SetFrequencyPrecision( 2 ); + setAxisTitle(QwtPlot::xBottom, QString("Frequency (%1)").arg(strunits.c_str())); } Reset(); @@ -461,7 +472,7 @@ void WaterfallDisplayPlot::_UpdateIntensityRangeDisplay(){ rightAxis->setColorBarEnabled(true); rightAxis->setColorMap(d_spectrogram->data()->range(), d_spectrogram->colorMap()); - + setAxisScale(QwtPlot::yRight, d_spectrogram->data()->range().minValue(), d_spectrogram->data()->range().maxValue() ); diff --git a/gr-qtgui/src/lib/WaterfallDisplayPlot.h b/gr-qtgui/src/lib/WaterfallDisplayPlot.h index 71fb76aa..d5371a03 100644 --- a/gr-qtgui/src/lib/WaterfallDisplayPlot.h +++ b/gr-qtgui/src/lib/WaterfallDisplayPlot.h @@ -18,11 +18,16 @@ public: void Reset(); - void SetFrequencyRange(const double, const double, const double, const bool); + void SetFrequencyRange(const double, const double, + const double, const bool, + const double units=1000.0, + const std::string &strunits = "kHz"); double GetStartFrequency()const; double GetStopFrequency()const; - void PlotNewData(const double* dataPoints, const int64_t numDataPoints, const double timePerFFT, const timespec timestamp, const int droppedFrames); + void PlotNewData(const double* dataPoints, const int64_t numDataPoints, + const double timePerFFT, const timespec timestamp, + const int droppedFrames); void SetIntensityRange(const double minIntensity, const double maxIntensity); diff --git a/gr-qtgui/src/lib/qtgui.i b/gr-qtgui/src/lib/qtgui.i index eba37833..1113d647 100644 --- a/gr-qtgui/src/lib/qtgui.i +++ b/gr-qtgui/src/lib/qtgui.i @@ -31,22 +31,37 @@ GR_SWIG_BLOCK_MAGIC(qtgui,sink_c) qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, float fmin=-0.5, float fmax=0.5, - const std::string &name="Display"); + const std::string &name="Display", + bool plotfreq=true, bool plotwaterfall=true, + bool plotwaterfall3d=true, bool plottime=true, + bool plotconst=true, + QWidget *parent=NULL); class qtgui_sink_c : public gr_block { private: friend qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, float fmin, float fmax, - const std::string &name); + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plotwaterfall3d, bool plottime, + bool plotconst, + QWidget *parent); qtgui_sink_c (int fftsize, int wintype, - float fmin, float fmax, const std::string &name); + float fmin, float fmax, + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plotwaterfall3d, bool plottime, + bool plotconst, + QWidget *parent); public: - void start_app(); - void initialize(); - void initialize(QApplication *qapp); - QApplication* get_qapplication(); + void exec_(); + PyObject* pyqwidget(); + + void set_frequency_range(const double centerfreq, + const double startfreq, + const double stopfreq); }; @@ -56,25 +71,34 @@ public: GR_SWIG_BLOCK_MAGIC(qtgui,sink_f) -qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, - const std::vector &window, - float fmin, float fmax, - const std::string &name="Display"); +qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype, + float fmin=-0.5, float fmax=0.5, + const std::string &name="Display", + bool plotfreq=true, bool plotwaterfall=true, + bool plotwaterfall3d=true, bool plottime=true, + bool plotconst=true, + QWidget *parent=NULL); class qtgui_sink_f : public gr_block { private: - friend qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, - const std::vector &window, - float fmin, float fmax, - const std::string &name); - qtgui_sink_f (int fftsize, - const std::vector &window, + friend qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype, + float fmin, float fmax, + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plotwaterfall3d, bool plottime, + bool plotconst, + QWidget *parent); + qtgui_sink_f (int fftsize, int wintype, float fmin, float fmax, - const std::string &name); - + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plotwaterfall3d, bool plottime, + bool plotconst, + QWidget *parent); + public: - void start_app(); + void exec_(); + PyObject* pyqwidget(); }; - diff --git a/gr-qtgui/src/lib/qtgui_sink_c.cc b/gr-qtgui/src/lib/qtgui_sink_c.cc index fdd069e7..a2b1366e 100644 --- a/gr-qtgui/src/lib/qtgui_sink_c.cc +++ b/gr-qtgui/src/lib/qtgui_sink_c.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -32,24 +32,46 @@ qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, - float fmin, float fmax, const std::string &name) + float fmin, float fmax, + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plotwaterfall3d, bool plottime, + bool plotconst, + QWidget *parent) { - return qtgui_sink_c_sptr (new qtgui_sink_c (fftsize, wintype, fmin, fmax, name)); + return qtgui_sink_c_sptr (new qtgui_sink_c (fftsize, wintype, + fmin, fmax, name, + plotfreq, plotwaterfall, + plotwaterfall3d, plottime, + plotconst, + parent)); } qtgui_sink_c::qtgui_sink_c (int fftsize, int wintype, - float fmin, float fmax, const std::string &name) + float fmin, float fmax, + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plotwaterfall3d, bool plottime, + bool plotconst, + QWidget *parent) : gr_block ("sink_c", gr_make_io_signature (1, -1, sizeof(gr_complex)), gr_make_io_signature (0, 0, 0)), - d_fftsize(fftsize), d_wintype((gr_firdes::win_type)(wintype)), - d_fmin(fmin), d_fmax(fmax), d_name(name) + d_fftsize(fftsize), + d_wintype((gr_firdes::win_type)(wintype)), + d_fmin(fmin), d_fmax(fmax), d_name(name), + d_plotfreq(plotfreq), d_plotwaterfall(plotwaterfall), + d_plotwaterfall3d(plotwaterfall3d), d_plottime(plottime), + d_plotconst(plotconst), + d_parent(parent) { d_main_gui = NULL; pthread_mutex_init(&d_pmutex, NULL); lock(); - d_shift = true; // Perform fftshift operation; this is usually desired when plotting + // Perform fftshift operation; + // this is usually desired when plotting + d_shift = true; d_fft = new gri_fft_complex (d_fftsize, true); @@ -60,7 +82,7 @@ qtgui_sink_c::qtgui_sink_c (int fftsize, int wintype, buildwindow(); - //initialize(); + initialize(); } qtgui_sink_c::~qtgui_sink_c() @@ -68,7 +90,6 @@ qtgui_sink_c::~qtgui_sink_c() delete d_object; delete [] d_fftdata; delete [] d_residbuf; - delete d_main_gui; delete d_fft; } @@ -86,47 +107,60 @@ void qtgui_sink_c::unlock() void qtgui_sink_c::initialize() { - int argc; - char **argv = NULL; - d_qApplication = new QApplication(argc, argv); - __initialize(); -} - - -void -qtgui_sink_c::initialize(QApplication *qapp) -{ - d_qApplication = qapp; - __initialize(); -} + if(qApp != NULL) { + d_qApplication = qApp; + } + else { + int argc; + char **argv = NULL; + d_qApplication = new QApplication(argc, argv); + } -void -qtgui_sink_c::__initialize() -{ uint64_t maxBufferSize = 32768; - d_main_gui = new SpectrumGUIClass(maxBufferSize, d_fftsize, d_fmin, d_fmax); + d_main_gui = new SpectrumGUIClass(maxBufferSize, d_fftsize, + d_fmin, d_fmax); + d_main_gui->SetDisplayTitle(d_name); d_main_gui->SetFFTSize(d_fftsize); d_main_gui->SetWindowType((int)d_wintype); - d_main_gui->OpenSpectrumWindow(NULL); + + d_main_gui->OpenSpectrumWindow(d_parent, + d_plotfreq, d_plotwaterfall, + d_plotwaterfall3d, d_plottime, + d_plotconst); d_object = new qtgui_obj(d_qApplication); qApp->postEvent(d_object, new qtgui_event(&d_pmutex)); } -QApplication* -qtgui_sink_c::get_qapplication() + +void +qtgui_sink_c::exec_() { - return d_qApplication; + d_qApplication->exec(); } +QWidget* +qtgui_sink_c::qwidget() +{ + return d_main_gui->qwidget(); +} -void -qtgui_sink_c::start_app() +PyObject* +qtgui_sink_c::pyqwidget() { - d_qApplication->exec(); + PyObject *w = PyLong_FromVoidPtr((void*)d_main_gui->qwidget()); + PyObject *retarg = Py_BuildValue("N", w); + return retarg; } +void +qtgui_sink_c::set_frequency_range(const double centerfreq, + const double startfreq, + const double stopfreq) +{ + d_main_gui->SetFrequencyRange(centerfreq, startfreq, stopfreq); +} void qtgui_sink_c::fft(const gr_complex *data_in, int size, gr_complex *data_out) @@ -221,37 +255,45 @@ qtgui_sink_c::general_work (int noutput_items, // Update the FFT size from the application fftresize(); windowreset(); + + const timespec currentTime = get_highres_clock(); + const timespec lastUpdateGUITime = d_main_gui->GetLastGUIUpdateTime(); - if(d_index) { - int filler = std::min(d_fftsize - d_index, noutput_items); + if(diff_timespec(currentTime, lastUpdateGUITime) > 0.25) { - memcpy(&d_residbuf[d_index], &in[0], sizeof(gr_complex)*filler); - d_index += filler; - i = filler; - j = filler; - } - - if(d_index == d_fftsize) { - d_index = 0; - fft(d_residbuf, d_fftsize, d_fftdata); + if(d_index) { + int filler = std::min(d_fftsize - d_index, noutput_items); + + memcpy(&d_residbuf[d_index], &in[0], sizeof(gr_complex)*filler); + d_index += filler; + i = filler; + j = filler; + } - d_main_gui->UpdateWindow(true, d_fftdata, d_fftsize, NULL, 0, (float*)d_residbuf, d_fftsize, - 1.0/4.0, convert_to_timespec(0.0), true); - } - - for(; i < noutput_items; i+=d_fftsize) { - if(noutput_items - i > d_fftsize) { - j += d_fftsize; - fft(&in[i], d_fftsize, d_fftdata); + if(d_index == d_fftsize) { + d_index = 0; + fft(d_residbuf, d_fftsize, d_fftdata); - d_main_gui->UpdateWindow(true, d_fftdata, d_fftsize, NULL, 0, (float*)&in[i], d_fftsize, + d_main_gui->UpdateWindow(true, d_fftdata, d_fftsize, NULL, 0, + (float*)d_residbuf, d_fftsize, 1.0/4.0, convert_to_timespec(0.0), true); } - } - - if(noutput_items > j) { - d_index = noutput_items - j; - memcpy(d_residbuf, &in[j], sizeof(gr_complex)*d_index); + + for(; i < noutput_items; i+=d_fftsize) { + if(noutput_items - i > d_fftsize) { + j += d_fftsize; + fft(&in[i], d_fftsize, d_fftdata); + + d_main_gui->UpdateWindow(true, d_fftdata, d_fftsize, NULL, 0, + (float*)&in[i], d_fftsize, + 1.0/4.0, convert_to_timespec(0.0), true); + } + } + + if(noutput_items > j) { + d_index = noutput_items - j; + memcpy(d_residbuf, &in[j], sizeof(gr_complex)*d_index); + } } pthread_mutex_unlock(&d_pmutex); diff --git a/gr-qtgui/src/lib/qtgui_sink_c.h b/gr-qtgui/src/lib/qtgui_sink_c.h index a1eb0564..305b1cf2 100644 --- a/gr-qtgui/src/lib/qtgui_sink_c.h +++ b/gr-qtgui/src/lib/qtgui_sink_c.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -28,25 +28,40 @@ #include #include #include +#include #include "SpectrumGUIClass.h" - class qtgui_sink_c; typedef boost::shared_ptr qtgui_sink_c_sptr; qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, - float fmin=-0.5, float fmax=0.5, const std::string &name="Display"); + float fmin=-0.5, float fmax=0.5, + const std::string &name="Spectrum Display", + bool plotfreq=true, bool plotwaterfall=true, + bool plotwaterfall3d=true, bool plottime=true, + bool plotconst=true, + QWidget *parent=NULL); class qtgui_sink_c : public gr_block { private: friend qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype, - float fmin, float fmax, const std::string &name); + float fmin, float fmax, + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plotwaterfall3d, bool plottime, + bool plotconst, + QWidget *parent); qtgui_sink_c (int fftsize, int wintype, - float fmin, float fmax, const std::string &name); + float fmin, float fmax, + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plotwaterfall3d, bool plottime, + bool plotconst, + QWidget *parent); + + void initialize(); - void __initialize(); - int d_fftsize; gr_firdes::win_type d_wintype; std::vector d_window; @@ -63,7 +78,10 @@ private: int d_index; gr_complex *d_residbuf; - SpectrumGUIClass *d_main_gui; + bool d_plotfreq, d_plotwaterfall, d_plotwaterfall3d, d_plottime, d_plotconst; + + QWidget *d_parent; + SpectrumGUIClass *d_main_gui; void windowreset(); void buildwindow(); @@ -72,13 +90,15 @@ private: public: ~qtgui_sink_c(); - void initialize(); - void initialize(QApplication *qapp); - void start_app(); + void exec_(); void lock(); void unlock(); + QWidget* qwidget(); + PyObject* pyqwidget(); - QApplication* get_qapplication(); + void set_frequency_range(const double centerfreq, + const double startfreq, + const double stopfreq); QApplication *d_qApplication; qtgui_obj *d_object; diff --git a/gr-qtgui/src/lib/qtgui_sink_f.cc b/gr-qtgui/src/lib/qtgui_sink_f.cc index b27718bd..94d4cf27 100644 --- a/gr-qtgui/src/lib/qtgui_sink_f.cc +++ b/gr-qtgui/src/lib/qtgui_sink_f.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -31,39 +31,65 @@ #include qtgui_sink_f_sptr -qtgui_make_sink_f (int fftsize, const std::vector &window, - float fmin, float fmax, const std::string &name) +qtgui_make_sink_f (int fftsize, int wintype, + float fmin, float fmax, + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plotwaterfall3d, bool plottime, + bool plotconst, + QWidget *parent) { - return qtgui_sink_f_sptr (new qtgui_sink_f (fftsize, window, fmin, fmax, name)); + return qtgui_sink_f_sptr (new qtgui_sink_f (fftsize, wintype, + fmin, fmax, name, + plotfreq, plotwaterfall, + plotwaterfall3d, plottime, + plotconst, + parent)); } -qtgui_sink_f::qtgui_sink_f (int fftsize, const std::vector &window, - float fmin, float fmax, const std::string &name) +qtgui_sink_f::qtgui_sink_f (int fftsize, int wintype, + float fmin, float fmax, + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plotwaterfall3d, bool plottime, + bool plotconst, + QWidget *parent) : gr_block ("sink_f", gr_make_io_signature (1, 1, sizeof(float)), gr_make_io_signature (0, 0, 0)), - d_fftsize(fftsize), d_window(window), - d_fmin(fmin), d_fmax(fmax), d_name(name) + d_fftsize(fftsize), + d_wintype((gr_firdes::win_type)(wintype)), + d_fmin(fmin), d_fmax(fmax), d_name(name), + d_plotfreq(plotfreq), d_plotwaterfall(plotwaterfall), + d_plotwaterfall3d(plotwaterfall3d), d_plottime(plottime), + d_plotconst(plotconst), + d_parent(parent) { d_main_gui = NULL; pthread_mutex_init(&d_pmutex, NULL); lock(); - d_shift = true; // Perform fftshift operation; this is usually desired when plotting + // Perform fftshift operation; + // this is usually desired when plotting + d_shift = true; d_fft = new gri_fft_complex (d_fftsize, true); - fftdata = new gr_complex[d_fftsize]; + d_fftdata = new gr_complex[d_fftsize]; d_index = 0; d_residbuf = new float[d_fftsize]; + + buildwindow(); + + initialize(); } qtgui_sink_f::~qtgui_sink_f() { - delete [] fftdata; + delete d_object; + delete [] d_fftdata; delete [] d_residbuf; - delete d_main_gui; delete d_fft; } @@ -78,21 +104,61 @@ void qtgui_sink_f::unlock() } void -qtgui_sink_f::start_app() +qtgui_sink_f::initialize() { - d_qApplication = new QApplication(0, NULL); + if(qApp != NULL) { + d_qApplication = qApp; + } + else { + int argc; + char **argv = NULL; + d_qApplication = new QApplication(argc, argv); + } + uint64_t maxBufferSize = 32768; - d_main_gui = new SpectrumGUIClass(maxBufferSize, d_fftsize, d_fmin, d_fmax); + d_main_gui = new SpectrumGUIClass(maxBufferSize, d_fftsize, + d_fmin, d_fmax); d_main_gui->SetDisplayTitle(d_name); - d_main_gui->OpenSpectrumWindow(NULL); + d_main_gui->SetFFTSize(d_fftsize); + d_main_gui->SetWindowType((int)d_wintype); + + d_main_gui->OpenSpectrumWindow(d_parent, + d_plotfreq, d_plotwaterfall, + d_plotwaterfall3d, d_plottime, + d_plotconst); - qtgui_obj object(d_qApplication); - qApp->postEvent(&object, new qtgui_event(&d_pmutex)); + d_object = new qtgui_obj(d_qApplication); + qApp->postEvent(d_object, new qtgui_event(&d_pmutex)); +} +void +qtgui_sink_f::exec_() +{ d_qApplication->exec(); } +QWidget* +qtgui_sink_f::qwidget() +{ + return d_main_gui->qwidget(); +} + +PyObject* +qtgui_sink_f::pyqwidget() +{ + PyObject *w = PyLong_FromVoidPtr((void*)d_main_gui->qwidget()); + PyObject *retarg = Py_BuildValue("N", w); + return retarg; +} + +void +qtgui_sink_f::set_frequency_range(const double centerfreq, + const double startfreq, + const double stopfreq) +{ + d_main_gui->SetFrequencyRange(centerfreq, startfreq, stopfreq); +} void qtgui_sink_f::fft(const float *data_in, int size, gr_complex *data_out) @@ -104,7 +170,7 @@ qtgui_sink_f::fft(const float *data_in, int size, gr_complex *data_out) } else { gr_complex *dst = d_fft->get_inbuf(); - for (unsigned int i = 0; i < size; i++) // float to complex conversion + for (int i = 0; i < size; i++) // float to complex conversion dst[i] = data_in[i]; } @@ -125,6 +191,54 @@ qtgui_sink_f::fft(const float *data_in, int size, gr_complex *data_out) } } +void +qtgui_sink_f::windowreset() +{ + gr_firdes::win_type newwintype = (gr_firdes::win_type)d_main_gui->GetWindowType(); + if(d_wintype != newwintype) { + d_wintype = newwintype; + buildwindow(); + } +} + +void +qtgui_sink_f::buildwindow() +{ + d_window.clear(); + if(d_wintype != 0) { + d_window = gr_firdes::window(d_wintype, d_fftsize, 6.76); + } +} + +void +qtgui_sink_f::fftresize() +{ + int newfftsize = d_main_gui->GetFFTSize(); + + if(newfftsize != d_fftsize) { + + // Resize the fftdata buffer; no need to preserve old data + delete [] d_fftdata; + d_fftdata = new gr_complex[newfftsize]; + + // Resize residbuf and replace data + delete [] d_residbuf; + d_residbuf = new float[newfftsize]; + + // Set new fft size and reset buffer index + // (throws away any currently held data, but who cares?) + d_fftsize = newfftsize; + d_index = 0; + + // Reset window to reflect new size + buildwindow(); + + // Reset FFTW plan for new size + delete d_fft; + d_fft = new gri_fft_complex (d_fftsize, true); + } +} + int qtgui_sink_f::general_work (int noutput_items, @@ -147,19 +261,21 @@ qtgui_sink_f::general_work (int noutput_items, if(d_index == d_fftsize) { d_index = 0; - fft(d_residbuf, d_fftsize, fftdata); + fft(d_residbuf, d_fftsize, d_fftdata); - d_main_gui->UpdateWindow(true, fftdata, d_fftsize, d_residbuf, d_fftsize, NULL, 0, + d_main_gui->UpdateWindow(true, d_fftdata, d_fftsize, + d_residbuf, d_fftsize, NULL, 0, 1.0/4.0, convert_to_timespec(0.0), true); } for(; i < noutput_items; i+=d_fftsize) { if(noutput_items - i > d_fftsize) { j += d_fftsize; - fft(&in[i], d_fftsize, fftdata); + fft(&in[i], d_fftsize, d_fftdata); - d_main_gui->UpdateWindow(true, fftdata, d_fftsize, &in[i], d_fftsize, NULL, 0, - 1.0/4.0, convert_to_timespec(0.0), true); + d_main_gui->UpdateWindow(true, d_fftdata, d_fftsize, &in[i], + d_fftsize, NULL, 0, 1.0/4.0, + convert_to_timespec(0.0), true); } } diff --git a/gr-qtgui/src/lib/qtgui_sink_f.h b/gr-qtgui/src/lib/qtgui_sink_f.h index 3f0e785c..f220bc6c 100644 --- a/gr-qtgui/src/lib/qtgui_sink_f.h +++ b/gr-qtgui/src/lib/qtgui_sink_f.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -24,27 +24,46 @@ #define INCLUDED_QTGUI_SINK_F_H #include +#include #include #include #include +#include #include "SpectrumGUIClass.h" - class qtgui_sink_f; typedef boost::shared_ptr qtgui_sink_f_sptr; -qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, const std::vector &window, - float fmin=-0.5, float fmax=0.5, const std::string &name="Display"); +qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype, + float fmin=-0.5, float fmax=0.5, + const std::string &name="Spectrum Display", + bool plotfreq=true, bool plotwaterfall=true, + bool plotwaterfall3d=true, bool plottime=true, + bool plotconst=true, + QWidget *parent=NULL); class qtgui_sink_f : public gr_block { private: - friend qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, const std::vector &window, - float fmin, float fmax, const std::string &name); - qtgui_sink_f (int fftsize, const std::vector &window, - float fmin, float fmax, const std::string &name); - + friend qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype, + float fmin, float fmax, + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plotwaterfall3d, bool plottime, + bool plotconst, + QWidget *parent); + qtgui_sink_f (int fftsize, int wintype, + float fmin, float fmax, + const std::string &name, + bool plotfreq, bool plotwaterfall, + bool plotwaterfall3d, bool plottime, + bool plotconst, + QWidget *parent); + + void initialize(); + int d_fftsize; + gr_firdes::win_type d_wintype; std::vector d_window; float d_fmin; float d_fmax; @@ -54,23 +73,35 @@ private: bool d_shift; gri_fft_complex *d_fft; - gr_complex *fftdata; + gr_complex *d_fftdata; int d_index; float *d_residbuf; + bool d_plotfreq, d_plotwaterfall, d_plotwaterfall3d, d_plottime, d_plotconst; + + QWidget *d_parent; SpectrumGUIClass *d_main_gui; + void windowreset(); + void buildwindow(); + void fftresize(); void fft(const float *data_in, int size, gr_complex *data_out); public: ~qtgui_sink_f(); - void start_app(); + void exec_(); void lock(); void unlock(); + QWidget* qwidget(); + PyObject* pyqwidget(); + + void set_frequency_range(const double centerfreq, + const double startfreq, + const double stopfreq); - QApplication *d_qApplication -; + QApplication *d_qApplication; + qtgui_obj *d_object; int general_work (int noutput_items, gr_vector_int &ninput_items, diff --git a/gr-qtgui/src/lib/spectrumUpdateEvents.cc b/gr-qtgui/src/lib/spectrumUpdateEvents.cc index f705e047..2da37d35 100644 --- a/gr-qtgui/src/lib/spectrumUpdateEvents.cc +++ b/gr-qtgui/src/lib/spectrumUpdateEvents.cc @@ -3,8 +3,19 @@ #include -SpectrumUpdateEvent::SpectrumUpdateEvent(const std::complex* fftPoints, const uint64_t numFFTDataPoints, const double* realTimeDomainPoints, const double* imagTimeDomainPoints, const uint64_t numTimeDomainDataPoints, const double timePerFFT, const timespec dataTimestamp, const bool repeatDataFlag, const bool lastOfMultipleUpdateFlag, const timespec generatedTimestamp, const int droppedFFTFrames):QEvent(QEvent::Type(10005)){ - +SpectrumUpdateEvent::SpectrumUpdateEvent(const std::complex* fftPoints, + const uint64_t numFFTDataPoints, + const double* realTimeDomainPoints, + const double* imagTimeDomainPoints, + const uint64_t numTimeDomainDataPoints, + const double timePerFFT, + const timespec dataTimestamp, + const bool repeatDataFlag, + const bool lastOfMultipleUpdateFlag, + const timespec generatedTimestamp, + const int droppedFFTFrames) + : QEvent(QEvent::Type(10005)) +{ _numFFTDataPoints = numFFTDataPoints; if(_numFFTDataPoints < 1){ _numFFTDataPoints = 1; @@ -22,13 +33,15 @@ SpectrumUpdateEvent::SpectrumUpdateEvent(const std::complex* fftPoints, c _realDataTimeDomainPoints = new double[_numTimeDomainDataPoints]; memset(_realDataTimeDomainPoints, 0x0, _numTimeDomainDataPoints*sizeof(double)); if(numTimeDomainDataPoints > 0){ - memcpy(_realDataTimeDomainPoints, realTimeDomainPoints, numTimeDomainDataPoints*sizeof(double)); + memcpy(_realDataTimeDomainPoints, realTimeDomainPoints, + numTimeDomainDataPoints*sizeof(double)); } _imagDataTimeDomainPoints = new double[_numTimeDomainDataPoints]; memset(_imagDataTimeDomainPoints, 0x0, _numTimeDomainDataPoints*sizeof(double)); if(numTimeDomainDataPoints > 0){ - memcpy(_imagDataTimeDomainPoints, imagTimeDomainPoints, numTimeDomainDataPoints*sizeof(double)); + memcpy(_imagDataTimeDomainPoints, imagTimeDomainPoints, + numTimeDomainDataPoints*sizeof(double)); } _dataTimestamp = dataTimestamp; _timePerFFT = timePerFFT; @@ -44,87 +57,126 @@ SpectrumUpdateEvent::~SpectrumUpdateEvent(){ delete[] _imagDataTimeDomainPoints; } -const std::complex* SpectrumUpdateEvent::getFFTPoints()const{ +const std::complex* +SpectrumUpdateEvent::getFFTPoints() const +{ return _fftPoints; } -const double* SpectrumUpdateEvent::getRealTimeDomainPoints()const{ +const double* +SpectrumUpdateEvent::getRealTimeDomainPoints() const +{ return _realDataTimeDomainPoints; } -const double* SpectrumUpdateEvent::getImagTimeDomainPoints()const{ +const double* +SpectrumUpdateEvent::getImagTimeDomainPoints() const +{ return _imagDataTimeDomainPoints; } -uint64_t SpectrumUpdateEvent::getNumFFTDataPoints()const{ +uint64_t +SpectrumUpdateEvent::getNumFFTDataPoints() const +{ return _numFFTDataPoints; } -uint64_t SpectrumUpdateEvent::getNumTimeDomainDataPoints()const{ +uint64_t +SpectrumUpdateEvent::getNumTimeDomainDataPoints() const +{ return _numTimeDomainDataPoints; } -double SpectrumUpdateEvent::getTimePerFFT()const{ +double +SpectrumUpdateEvent::getTimePerFFT() const +{ return _timePerFFT; } -timespec SpectrumUpdateEvent::getDataTimestamp()const{ +timespec +SpectrumUpdateEvent::getDataTimestamp() const +{ return _dataTimestamp; } -bool SpectrumUpdateEvent::getRepeatDataFlag()const{ +bool +SpectrumUpdateEvent::getRepeatDataFlag() const +{ return _repeatDataFlag; } -bool SpectrumUpdateEvent::getLastOfMultipleUpdateFlag()const{ +bool +SpectrumUpdateEvent::getLastOfMultipleUpdateFlag() const +{ return _lastOfMultipleUpdateFlag; } -timespec SpectrumUpdateEvent::getEventGeneratedTimestamp()const{ +timespec +SpectrumUpdateEvent::getEventGeneratedTimestamp() const +{ return _eventGeneratedTimestamp; } -int SpectrumUpdateEvent::getDroppedFFTFrames()const{ +int +SpectrumUpdateEvent::getDroppedFFTFrames() const +{ return _droppedFFTFrames; } -SpectrumWindowCaptionEvent::SpectrumWindowCaptionEvent(const QString& newLbl):QEvent(QEvent::Type(10008)){ +SpectrumWindowCaptionEvent::SpectrumWindowCaptionEvent(const QString& newLbl) + : QEvent(QEvent::Type(10008)) +{ _labelString = newLbl; } -SpectrumWindowCaptionEvent::~SpectrumWindowCaptionEvent(){ +SpectrumWindowCaptionEvent::~SpectrumWindowCaptionEvent() +{ } -QString SpectrumWindowCaptionEvent::getLabel(){ +QString +SpectrumWindowCaptionEvent::getLabel() +{ return _labelString; } -SpectrumWindowResetEvent::SpectrumWindowResetEvent():QEvent(QEvent::Type(10009)){ +SpectrumWindowResetEvent::SpectrumWindowResetEvent() + : QEvent(QEvent::Type(10009)) +{ } -SpectrumWindowResetEvent::~SpectrumWindowResetEvent(){ - +SpectrumWindowResetEvent::~SpectrumWindowResetEvent() +{ } - SpectrumFrequencyRangeEvent::SpectrumFrequencyRangeEvent(const double centerFreq, const double startFreq, const double stopFreq):QEvent(QEvent::Type(10010)){ +SpectrumFrequencyRangeEvent::SpectrumFrequencyRangeEvent(const double centerFreq, + const double startFreq, + const double stopFreq) + : QEvent(QEvent::Type(10010)) +{ _centerFrequency = centerFreq; _startFrequency = startFreq; _stopFrequency = stopFreq; } -SpectrumFrequencyRangeEvent::~SpectrumFrequencyRangeEvent(){ - +SpectrumFrequencyRangeEvent::~SpectrumFrequencyRangeEvent() +{ } -double SpectrumFrequencyRangeEvent::GetCenterFrequency()const{ +double +SpectrumFrequencyRangeEvent::GetCenterFrequency() const +{ return _centerFrequency; } -double SpectrumFrequencyRangeEvent::GetStartFrequency()const{ +double +SpectrumFrequencyRangeEvent::GetStartFrequency() const +{ return _startFrequency; } -double SpectrumFrequencyRangeEvent::GetStopFrequency()const{ +double +SpectrumFrequencyRangeEvent::GetStopFrequency() const +{ return _stopFrequency; } diff --git a/gr-qtgui/src/lib/spectrumdisplayform.cc b/gr-qtgui/src/lib/spectrumdisplayform.cc index 4beec9bd..3249463d 100644 --- a/gr-qtgui/src/lib/spectrumdisplayform.cc +++ b/gr-qtgui/src/lib/spectrumdisplayform.cc @@ -5,14 +5,16 @@ int SpectrumDisplayForm::_openGLWaterfall3DFlag = -1; -SpectrumDisplayForm::SpectrumDisplayForm(QWidget* parent) : QDialog(parent){ +SpectrumDisplayForm::SpectrumDisplayForm(QWidget* parent) + : QWidget(parent) +{ setupUi(this); - + _systemSpecifiedFlag = false; _intValidator = new QIntValidator(this); _intValidator->setBottom(0); - _frequencyDisplayPlot = new FrequencyDisplayPlot(Tab1PlotDisplayFrame); - _waterfallDisplayPlot = new WaterfallDisplayPlot(Tab2PlotDisplayFrame); + _frequencyDisplayPlot = new FrequencyDisplayPlot(FrequencyPlotDisplayFrame); + _waterfallDisplayPlot = new WaterfallDisplayPlot(WaterfallPlotDisplayFrame); _waterfall3DDisplayPlot = new Waterfall3DDisplayPlot(Waterfall3DPlotDisplayFrame); _timeDomainDisplayPlot = new TimeDomainDisplayPlot(TimeDomainDisplayFrame); _constellationDisplayPlot = new ConstellationDisplayPlot(ConstellationDisplayFrame); @@ -42,7 +44,7 @@ SpectrumDisplayForm::SpectrumDisplayForm(QWidget* parent) : QDialog(parent){ _peakAmplitude = -HUGE_VAL; _noiseFloorAmplitude = -HUGE_VAL; - + connect(_waterfallDisplayPlot, SIGNAL(UpdatedLowerIntensityLevel(const double)), _frequencyDisplayPlot, SLOT(SetLowerIntensityLevel(const double))); connect(_waterfallDisplayPlot, SIGNAL(UpdatedUpperIntensityLevel(const double)), @@ -50,16 +52,23 @@ SpectrumDisplayForm::SpectrumDisplayForm(QWidget* parent) : QDialog(parent){ _frequencyDisplayPlot->SetLowerIntensityLevel(-200); _frequencyDisplayPlot->SetUpperIntensityLevel(-200); - + // Load up the acceptable FFT sizes... FFTSizeComboBox->clear(); for(long fftSize = SpectrumGUIClass::MIN_FFT_SIZE; fftSize <= SpectrumGUIClass::MAX_FFT_SIZE; fftSize *= 2){ FFTSizeComboBox->insertItem(FFTSizeComboBox->count(), QString("%1").arg(fftSize)); } Reset(); + + ToggleTabFrequency(false); + ToggleTabWaterfall(false); + ToggleTabWaterfall3D(false); + ToggleTabTime(false); + ToggleTabConstellation(false); } -SpectrumDisplayForm::~SpectrumDisplayForm(){ +SpectrumDisplayForm::~SpectrumDisplayForm() +{ // Qt deletes children when parent is deleted // Don't worry about deleting Display Plots - they are deleted when parents are deleted @@ -75,9 +84,10 @@ SpectrumDisplayForm::~SpectrumDisplayForm(){ delete _historyVector; } -void SpectrumDisplayForm::setSystem( SpectrumGUIClass * newSystem, - const uint64_t numFFTDataPoints, - const uint64_t numTimeDomainDataPoints ) +void +SpectrumDisplayForm::setSystem( SpectrumGUIClass * newSystem, + const uint64_t numFFTDataPoints, + const uint64_t numTimeDomainDataPoints ) { ResizeBuffers(numFFTDataPoints, numTimeDomainDataPoints); @@ -90,7 +100,8 @@ void SpectrumDisplayForm::setSystem( SpectrumGUIClass * newSystem, } } -void SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumUpdateEvent) +void +SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumUpdateEvent) { const std::complex* complexDataPoints = spectrumUpdateEvent->getFFTPoints(); const uint64_t numFFTDataPoints = spectrumUpdateEvent->getNumFFTDataPoints(); @@ -116,12 +127,14 @@ void SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumU // 75 ohm load assumption // 10 * log10 (v^2 / (2 * 75.0 * .001)) = 10 * log10( v^2 * 15) - *realFFTDataPointsPtr = 10.0*log10((((*complexDataPointsPtr).real() * (*complexDataPointsPtr).real()) + ((*complexDataPointsPtr).imag()*(*complexDataPointsPtr).imag())) + 1e-20); + *realFFTDataPointsPtr = 10.0*log10((((*complexDataPointsPtr).real() * (*complexDataPointsPtr).real()) + + ((*complexDataPointsPtr).imag()*(*complexDataPointsPtr).imag())) + 1e-20); complexDataPointsPtr++; realFFTDataPointsPtr++; } + int tabindex = SpectrumTypeTab->currentIndex(); // Don't update the averaging history if this is repeated data if(!repeatDataFlag){ @@ -167,36 +180,46 @@ void SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumU } if(lastOfMultipleUpdatesFlag){ - _frequencyDisplayPlot->PlotNewData(_averagedValues, numFFTDataPoints, - _noiseFloorAmplitude, _peakFrequency, - _peakAmplitude); - _timeDomainDisplayPlot->PlotNewData(realTimeDomainDataPoints, - imagTimeDomainDataPoints, - numTimeDomainDataPoints); - _constellationDisplayPlot->PlotNewData(realTimeDomainDataPoints, - imagTimeDomainDataPoints, - numTimeDomainDataPoints); - } - // Don't update the repeated data for the waterfall - if(!repeatDataFlag){ - _waterfallDisplayPlot->PlotNewData(_realFFTDataPoints, numFFTDataPoints, - timePerFFT, dataTimestamp, - spectrumUpdateEvent->getDroppedFFTFrames()); - if( _openGLWaterfall3DFlag == 1 ){ - _waterfall3DDisplayPlot->PlotNewData(_realFFTDataPoints, numFFTDataPoints, + if(tabindex == d_plot_fft) { + _frequencyDisplayPlot->PlotNewData(_averagedValues, numFFTDataPoints, + _noiseFloorAmplitude, _peakFrequency, + _peakAmplitude); + } + if(tabindex == d_plot_time) { + _timeDomainDisplayPlot->PlotNewData(realTimeDomainDataPoints, + imagTimeDomainDataPoints, + numTimeDomainDataPoints); + } + if(tabindex == d_plot_constellation) { + _constellationDisplayPlot->PlotNewData(realTimeDomainDataPoints, + imagTimeDomainDataPoints, + numTimeDomainDataPoints); + } + + // Don't update the repeated data for the waterfall + if(!repeatDataFlag){ + if(tabindex == d_plot_waterfall) { + _waterfallDisplayPlot->PlotNewData(_realFFTDataPoints, numFFTDataPoints, timePerFFT, dataTimestamp, spectrumUpdateEvent->getDroppedFFTFrames()); + } + if( _openGLWaterfall3DFlag == 1 && (tabindex == d_plot_waterfall3d)) { + _waterfall3DDisplayPlot->PlotNewData(_realFFTDataPoints, numFFTDataPoints, + timePerFFT, dataTimestamp, + spectrumUpdateEvent->getDroppedFFTFrames()); + } + } + + // Tell the system the GUI has been updated + if(_systemSpecifiedFlag){ + _system->SetLastGUIUpdateTime(generatedTimestamp); + _system->DecrementPendingGUIUpdateEvents(); } - } - - // Tell the system the GUI has been updated - if(_systemSpecifiedFlag){ - _system->SetLastGUIUpdateTime(generatedTimestamp); - _system->DecrementPendingGUIUpdateEvents(); } } -void SpectrumDisplayForm::resizeEvent( QResizeEvent *e ) +void +SpectrumDisplayForm::resizeEvent( QResizeEvent *e ) { // Let the actual window resize its width, but not its height QSize newSize(e->size().width(), e->oldSize().height()); @@ -207,29 +230,38 @@ void SpectrumDisplayForm::resizeEvent( QResizeEvent *e ) SpectrumTypeTab->resize( e->size().width(), e->size().height()-60); // Tell the TabXFreqDisplay to resize - //Tab1PlotDisplayFrame->resize(e->size().width()-4, - //Tab1PlotDisplayFrame->height()); - Tab1PlotDisplayFrame->resize(e->size().width()-4, - e->size().height()-140); - Tab2PlotDisplayFrame->resize(e->size().width()-4, - e->size().height()-140); - Waterfall3DPlotDisplayFrame->resize(e->size().width()-4, - e->size().height()-140); - TimeDomainDisplayFrame->resize(e->size().width()-4, - e->size().height()-140); - ConstellationDisplayFrame->resize(e->size().width()-4, + FrequencyPlotDisplayFrame->resize(e->size().width()-4, e->size().height()-140); - _frequencyDisplayPlot->resize( Tab1PlotDisplayFrame->width()-4, - e->size().height()-140); - _waterfallDisplayPlot->resize( Tab2PlotDisplayFrame->width()-4, + _frequencyDisplayPlot->resize( FrequencyPlotDisplayFrame->width()-4, e->size().height()-140); - _waterfall3DDisplayPlot->resize( Waterfall3DPlotDisplayFrame->width()-4, - e->size().height()-140); - _timeDomainDisplayPlot->resize( TimeDomainDisplayFrame->width()-4, - e->size().height()-140); - _constellationDisplayPlot->resize( TimeDomainDisplayFrame->width()-4, - e->size().height()-140); + + // Move the Power Lbl and Line Edit + PowerLabel->move(e->size().width()-(415-324) - PowerLabel->width(), + e->size().height()-135); + PowerLineEdit->move(e->size().width()-(415-318) - PowerLineEdit->width(), + e->size().height()-115); + + // Move the Avg Lbl and Line Edit + AvgLabel->move(e->size().width()-(415-406) - AvgLabel->width(), + e->size().height()-135); + AvgLineEdit->move(e->size().width()-(415-400) - AvgLineEdit->width(), + e->size().height()-115); + + // Move Max and Min check boxes + MaxHoldCheckBox->move(MaxHoldCheckBox->x(), + e->size().height()-135); + MaxHoldResetBtn->move(MaxHoldResetBtn->x(), + e->size().height()-135); + MinHoldCheckBox->move(MinHoldCheckBox->x(), + e->size().height()-115); + MinHoldResetBtn->move(MinHoldResetBtn->x(), + e->size().height()-115); + WaterfallPlotDisplayFrame->resize(e->size().width()-4, + e->size().height()-140); + _waterfallDisplayPlot->resize( WaterfallPlotDisplayFrame->width()-4, + e->size().height()-140); + // Move the IntensityWheels and Labels WaterfallMaximumIntensityLabel->move(width() - 5 - WaterfallMaximumIntensityLabel->width(), @@ -237,7 +269,7 @@ void SpectrumDisplayForm::resizeEvent( QResizeEvent *e ) WaterfallMaximumIntensityWheel->resize(WaterfallMaximumIntensityLabel->x() - 5 - WaterfallMaximumIntensityWheel->x(), WaterfallMaximumIntensityWheel->height()); - + WaterfallMinimumIntensityLabel->move(width() - 5 - WaterfallMinimumIntensityLabel->width(), height() - 115); @@ -246,14 +278,20 @@ void SpectrumDisplayForm::resizeEvent( QResizeEvent *e ) WaterfallMaximumIntensityWheel->height()); WaterfallMinimumIntensityWheel->move(WaterfallMinimumIntensityWheel->x(), height() - 115); - + WaterfallAutoScaleBtn->move(WaterfallAutoScaleBtn->x(), + e->size().height()-115); + + Waterfall3DPlotDisplayFrame->resize(e->size().width()-4, + e->size().height()-140); + _waterfall3DDisplayPlot->resize( Waterfall3DPlotDisplayFrame->width()-4, + e->size().height()-140); + Waterfall3DMaximumIntensityLabel->move(width() - 5 - Waterfall3DMaximumIntensityLabel->width(), Waterfall3DMaximumIntensityLabel->y()); Waterfall3DMaximumIntensityWheel->resize(Waterfall3DMaximumIntensityLabel->x() - 5 - Waterfall3DMaximumIntensityWheel->x(), Waterfall3DMaximumIntensityWheel->height()); - Waterfall3DMinimumIntensityLabel->move(width() - 5 - Waterfall3DMinimumIntensityLabel->width(), height() - 115); @@ -262,42 +300,25 @@ void SpectrumDisplayForm::resizeEvent( QResizeEvent *e ) Waterfall3DMaximumIntensityWheel->height()); Waterfall3DMinimumIntensityWheel->move(Waterfall3DMinimumIntensityWheel->x(), height() - 115); - - // Move Waterfall and Waterfall3D Auto Scan button - WaterfallAutoScaleBtn->move(WaterfallAutoScaleBtn->x(), - e->size().height()-115); Waterfall3DAutoScaleBtn->move(WaterfallAutoScaleBtn->x(), - e->size().height()-115); + e->size().height()-115); - - // Move the Power Lbl and Line Edit - PowerLabel->move(e->size().width()-(415-324) - PowerLabel->width(), - e->size().height()-135); - PowerLineEdit->move(e->size().width()-(415-318) - PowerLineEdit->width(), - e->size().height()-115); - - // Move the Avg Lbl and Line Edit - AvgLabel->move(e->size().width()-(415-406) - AvgLabel->width(), - e->size().height()-135); - AvgLineEdit->move(e->size().width()-(415-400) - AvgLineEdit->width(), - e->size().height()-115); - - // Move Max and Min check boxes - MaxHoldCheckBox->move(MaxHoldCheckBox->x(), - e->size().height()-135); - MaxHoldResetBtn->move(MaxHoldResetBtn->x(), - e->size().height()-135); - MinHoldCheckBox->move(MinHoldCheckBox->x(), - e->size().height()-115); - MinHoldResetBtn->move(MinHoldResetBtn->x(), - e->size().height()-115); + TimeDomainDisplayFrame->resize(e->size().width()-4, + e->size().height()-140); + _timeDomainDisplayPlot->resize( TimeDomainDisplayFrame->width()-4, + e->size().height()-140); + + ConstellationDisplayFrame->resize(e->size().width()-4, + e->size().height()-140); + _constellationDisplayPlot->resize( TimeDomainDisplayFrame->width()-4, + e->size().height()-140); // Move the FFT Size Combobox and label FFTSizeComboBox->move(width() - 5 - FFTSizeComboBox->width(), height()-50); FFTSizeLabel->move(width() - 10 - FFTSizeComboBox->width() - FFTSizeLabel->width(), height()-50); - + // Move the lower check and combo boxes UseRFFrequenciesCheckBox->move(UseRFFrequenciesCheckBox->x(), height()-50); WindowLbl->move(WindowLbl->x(), height()-25); @@ -305,7 +326,8 @@ void SpectrumDisplayForm::resizeEvent( QResizeEvent *e ) } -void SpectrumDisplayForm::customEvent( QEvent * e) +void +SpectrumDisplayForm::customEvent( QEvent * e) { if(e->type() == QEvent::User+3){ if(_systemSpecifiedFlag){ @@ -337,15 +359,13 @@ void SpectrumDisplayForm::customEvent( QEvent * e) _openGLWaterfall3DFlag = 1; } } - + if(_openGLWaterfall3DFlag != 1){ - SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(Waterfall3DPage)); + ToggleTabWaterfall3D(false); } // Clear any previous display Reset(); - - show(); } else if(e->type() == 10005){ SpectrumUpdateEvent* spectrumUpdateEvent = (SpectrumUpdateEvent*)e; @@ -369,7 +389,8 @@ void SpectrumDisplayForm::customEvent( QEvent * e) } } -void SpectrumDisplayForm::AvgLineEdit_textChanged( const QString &valueString ) +void +SpectrumDisplayForm::AvgLineEdit_textChanged( const QString &valueString ) { if(!valueString.isEmpty()){ int value = valueString.toInt(); @@ -382,7 +403,8 @@ void SpectrumDisplayForm::AvgLineEdit_textChanged( const QString &valueString ) } -void SpectrumDisplayForm::MaxHoldCheckBox_toggled( bool newState ) +void +SpectrumDisplayForm::MaxHoldCheckBox_toggled( bool newState ) { MaxHoldResetBtn->setEnabled(newState); _frequencyDisplayPlot->SetMaxFFTVisible(newState); @@ -390,7 +412,8 @@ void SpectrumDisplayForm::MaxHoldCheckBox_toggled( bool newState ) } -void SpectrumDisplayForm::MinHoldCheckBox_toggled( bool newState ) +void +SpectrumDisplayForm::MinHoldCheckBox_toggled( bool newState ) { MinHoldResetBtn->setEnabled(newState); _frequencyDisplayPlot->SetMinFFTVisible(newState); @@ -398,21 +421,24 @@ void SpectrumDisplayForm::MinHoldCheckBox_toggled( bool newState ) } -void SpectrumDisplayForm::MinHoldResetBtn_clicked() +void +SpectrumDisplayForm::MinHoldResetBtn_clicked() { _frequencyDisplayPlot->ClearMinData(); _frequencyDisplayPlot->replot(); } -void SpectrumDisplayForm::MaxHoldResetBtn_clicked() +void +SpectrumDisplayForm::MaxHoldResetBtn_clicked() { _frequencyDisplayPlot->ClearMaxData(); _frequencyDisplayPlot->replot(); } -void SpectrumDisplayForm::PowerLineEdit_textChanged( const QString &valueString ) +void +SpectrumDisplayForm::PowerLineEdit_textChanged( const QString &valueString ) { if(_systemSpecifiedFlag){ if(!valueString.isEmpty()){ @@ -435,18 +461,47 @@ void SpectrumDisplayForm::PowerLineEdit_textChanged( const QString &valueString } } -void SpectrumDisplayForm::SetFrequencyRange(const double newStartFrequency, const double newStopFrequency, const double newCenterFrequency){ - _frequencyDisplayPlot->SetFrequencyRange(newStartFrequency, newStopFrequency, newCenterFrequency, UseRFFrequenciesCheckBox->isChecked()); - _waterfallDisplayPlot->SetFrequencyRange(newStartFrequency, newStopFrequency, newCenterFrequency, UseRFFrequenciesCheckBox->isChecked()); - _waterfall3DDisplayPlot->SetFrequencyRange(newStartFrequency, newStopFrequency, newCenterFrequency, UseRFFrequenciesCheckBox->isChecked()); - +void +SpectrumDisplayForm::SetFrequencyRange(const double newStartFrequency, + const double newStopFrequency, + const double newCenterFrequency) +{ + double fdiff = abs(newStartFrequency - newStopFrequency); + + if(fdiff > 0) { + std::string strunits[4] = {"Hz", "kHz", "MHz", "GHz"}; + double units10 = floor(log10(fdiff)); + double units3 = floor(units10 / 3.0); + double units = pow(10, units10); + int iunit = static_cast(units3); + + _frequencyDisplayPlot->SetFrequencyRange(newStartFrequency, + newStopFrequency, + newCenterFrequency, + UseRFFrequenciesCheckBox->isChecked(), + units, strunits[iunit]); + _waterfallDisplayPlot->SetFrequencyRange(newStartFrequency, + newStopFrequency, + newCenterFrequency, + UseRFFrequenciesCheckBox->isChecked(), + units, strunits[iunit]); + _waterfall3DDisplayPlot->SetFrequencyRange(newStartFrequency, + newStopFrequency, + newCenterFrequency, + UseRFFrequenciesCheckBox->isChecked(), + units, strunits[iunit]); + } } -int SpectrumDisplayForm::GetAverageCount(){ +int +SpectrumDisplayForm::GetAverageCount() +{ return _historyVector->size(); } -void SpectrumDisplayForm::SetAverageCount(const int newCount){ +void +SpectrumDisplayForm::SetAverageCount(const int newCount) +{ if(newCount > -1){ if(newCount != static_cast(_historyVector->size())){ std::vector::iterator pos; @@ -464,10 +519,13 @@ void SpectrumDisplayForm::SetAverageCount(const int newCount){ } } -void SpectrumDisplayForm::_AverageHistory(const double* newBuffer){ +void +SpectrumDisplayForm::_AverageHistory(const double* newBuffer) +{ if(_numRealDataPoints > 0){ if(_historyVector->size() > 0){ - memcpy(_historyVector->operator[](_historyEntry), newBuffer, _numRealDataPoints*sizeof(double)); + memcpy(_historyVector->operator[](_historyEntry), newBuffer, + _numRealDataPoints*sizeof(double)); // Increment the next location to store data _historyEntryCount++; @@ -492,7 +550,10 @@ void SpectrumDisplayForm::_AverageHistory(const double* newBuffer){ } } -void SpectrumDisplayForm::ResizeBuffers( const uint64_t numFFTDataPoints, const uint64_t /*numTimeDomainDataPoints*/ ){ +void +SpectrumDisplayForm::ResizeBuffers( const uint64_t numFFTDataPoints, + const uint64_t /*numTimeDomainDataPoints*/ ) +{ // Convert from Complex to Real for certain Displays if(_numRealDataPoints != numFFTDataPoints){ _numRealDataPoints = numFFTDataPoints; @@ -511,7 +572,9 @@ void SpectrumDisplayForm::ResizeBuffers( const uint64_t numFFTDataPoints, const } } -void SpectrumDisplayForm::Reset(){ +void +SpectrumDisplayForm::Reset() +{ AverageDataReset(); _waterfallDisplayPlot->Reset(); @@ -519,7 +582,9 @@ void SpectrumDisplayForm::Reset(){ } -void SpectrumDisplayForm::AverageDataReset(){ +void +SpectrumDisplayForm::AverageDataReset() +{ _historyEntry = 0; _historyEntryCount = 0; @@ -530,7 +595,8 @@ void SpectrumDisplayForm::AverageDataReset(){ } -void SpectrumDisplayForm::closeEvent( QCloseEvent *e ) +void +SpectrumDisplayForm::closeEvent( QCloseEvent *e ) { if(_systemSpecifiedFlag){ _system->SetWindowOpenFlag(false); @@ -542,7 +608,8 @@ void SpectrumDisplayForm::closeEvent( QCloseEvent *e ) } -void SpectrumDisplayForm::WindowTypeChanged( int newItem ) +void +SpectrumDisplayForm::WindowTypeChanged( int newItem ) { if(_systemSpecifiedFlag){ _system->SetWindowType(newItem); @@ -550,7 +617,8 @@ void SpectrumDisplayForm::WindowTypeChanged( int newItem ) } -void SpectrumDisplayForm::UseRFFrequenciesCB( bool useRFFlag ) +void +SpectrumDisplayForm::UseRFFrequenciesCB( bool useRFFlag ) { if(useRFFlag){ SetFrequencyRange(_startFrequency, _stopFrequency, _centerFrequency); @@ -561,7 +629,8 @@ void SpectrumDisplayForm::UseRFFrequenciesCB( bool useRFFlag ) } -void SpectrumDisplayForm::waterfallMaximumIntensityChangedCB( double newValue ) +void +SpectrumDisplayForm::waterfallMaximumIntensityChangedCB( double newValue ) { if(newValue > WaterfallMinimumIntensityWheel->value()){ WaterfallMaximumIntensityLabel->setText(QString("%1 dB").arg(newValue, 0, 'f', 0)); @@ -569,11 +638,14 @@ void SpectrumDisplayForm::waterfallMaximumIntensityChangedCB( double newValue ) else{ WaterfallMaximumIntensityWheel->setValue(WaterfallMinimumIntensityWheel->value()); } - _waterfallDisplayPlot->SetIntensityRange(WaterfallMinimumIntensityWheel->value(), WaterfallMaximumIntensityWheel->value()); + + _waterfallDisplayPlot->SetIntensityRange(WaterfallMinimumIntensityWheel->value(), + WaterfallMaximumIntensityWheel->value()); } -void SpectrumDisplayForm::waterfallMinimumIntensityChangedCB( double newValue ) +void +SpectrumDisplayForm::waterfallMinimumIntensityChangedCB( double newValue ) { if(newValue < WaterfallMaximumIntensityWheel->value()){ WaterfallMinimumIntensityLabel->setText(QString("%1 dB").arg(newValue, 0, 'f', 0)); @@ -581,10 +653,13 @@ void SpectrumDisplayForm::waterfallMinimumIntensityChangedCB( double newValue ) else{ WaterfallMinimumIntensityWheel->setValue(WaterfallMaximumIntensityWheel->value()); } - _waterfallDisplayPlot->SetIntensityRange(WaterfallMinimumIntensityWheel->value(), WaterfallMaximumIntensityWheel->value()); + + _waterfallDisplayPlot->SetIntensityRange(WaterfallMinimumIntensityWheel->value(), + WaterfallMaximumIntensityWheel->value()); } -void SpectrumDisplayForm::waterfall3DMaximumIntensityChangedCB( double newValue ) +void +SpectrumDisplayForm::waterfall3DMaximumIntensityChangedCB( double newValue ) { if(newValue > Waterfall3DMinimumIntensityWheel->value()){ Waterfall3DMaximumIntensityLabel->setText(QString("%1 dB").arg(newValue, 0, 'f', 0)); @@ -592,11 +667,14 @@ void SpectrumDisplayForm::waterfall3DMaximumIntensityChangedCB( double newValue else{ Waterfall3DMaximumIntensityWheel->setValue(Waterfall3DMinimumIntensityWheel->value()); } - _waterfall3DDisplayPlot->SetIntensityRange(Waterfall3DMinimumIntensityWheel->value(), Waterfall3DMaximumIntensityWheel->value()); + + _waterfall3DDisplayPlot->SetIntensityRange(Waterfall3DMinimumIntensityWheel->value(), + Waterfall3DMaximumIntensityWheel->value()); } -void SpectrumDisplayForm::waterfall3DMinimumIntensityChangedCB( double newValue ) +void +SpectrumDisplayForm::waterfall3DMinimumIntensityChangedCB( double newValue ) { if(newValue < Waterfall3DMaximumIntensityWheel->value()){ Waterfall3DMinimumIntensityLabel->setText(QString("%1 dB").arg(newValue, 0, 'f', 0)); @@ -604,11 +682,14 @@ void SpectrumDisplayForm::waterfall3DMinimumIntensityChangedCB( double newValue else{ Waterfall3DMinimumIntensityWheel->setValue(Waterfall3DMaximumIntensityWheel->value()); } - _waterfall3DDisplayPlot->SetIntensityRange(Waterfall3DMinimumIntensityWheel->value(), Waterfall3DMaximumIntensityWheel->value()); + + _waterfall3DDisplayPlot->SetIntensityRange(Waterfall3DMinimumIntensityWheel->value(), + Waterfall3DMaximumIntensityWheel->value()); } -void SpectrumDisplayForm::FFTComboBoxSelectedCB( const QString &fftSizeString ) +void +SpectrumDisplayForm::FFTComboBoxSelectedCB( const QString &fftSizeString ) { if(_systemSpecifiedFlag){ _system->SetFFTSize(fftSizeString.toLong()); @@ -616,7 +697,8 @@ void SpectrumDisplayForm::FFTComboBoxSelectedCB( const QString &fftSizeString ) } -void SpectrumDisplayForm::WaterfallAutoScaleBtnCB() +void +SpectrumDisplayForm::WaterfallAutoScaleBtnCB() { double minimumIntensity = _noiseFloorAmplitude - 5; if(minimumIntensity < WaterfallMinimumIntensityWheel->minValue()){ @@ -631,7 +713,8 @@ void SpectrumDisplayForm::WaterfallAutoScaleBtnCB() waterfallMaximumIntensityChangedCB(maximumIntensity); } -void SpectrumDisplayForm::Waterfall3DAutoScaleBtnCB() +void +SpectrumDisplayForm::Waterfall3DAutoScaleBtnCB() { double minimumIntensity = _noiseFloorAmplitude - 5; if(minimumIntensity < Waterfall3DMinimumIntensityWheel->minValue()){ @@ -646,7 +729,8 @@ void SpectrumDisplayForm::Waterfall3DAutoScaleBtnCB() waterfallMaximumIntensityChangedCB(maximumIntensity); } -void SpectrumDisplayForm::WaterfallIntensityColorTypeChanged( int newType ) +void +SpectrumDisplayForm::WaterfallIntensityColorTypeChanged( int newType ) { QColor lowIntensityColor; QColor highIntensityColor; @@ -658,7 +742,7 @@ void SpectrumDisplayForm::WaterfallIntensityColorTypeChanged( int newType ) } QMessageBox::information(this, "Low Intensity Color Selection", "In the next window, select the low intensity color for the waterfall display", QMessageBox::Ok); lowIntensityColor = QColorDialog::getColor(lowIntensityColor, this); - + // Select the High Intensity Color highIntensityColor = _waterfallDisplayPlot->GetUserDefinedHighIntensityColor(); if(!highIntensityColor.isValid()){ @@ -667,10 +751,12 @@ void SpectrumDisplayForm::WaterfallIntensityColorTypeChanged( int newType ) QMessageBox::information(this, "High Intensity Color Selection", "In the next window, select the high intensity color for the waterfall display", QMessageBox::Ok); highIntensityColor = QColorDialog::getColor(highIntensityColor, this); } + _waterfallDisplayPlot->SetIntensityColorMapType(newType, lowIntensityColor, highIntensityColor); } -void SpectrumDisplayForm::Waterfall3DIntensityColorTypeChanged( int newType ) +void +SpectrumDisplayForm::Waterfall3DIntensityColorTypeChanged( int newType ) { QColor lowIntensityColor; QColor highIntensityColor; @@ -682,7 +768,7 @@ void SpectrumDisplayForm::Waterfall3DIntensityColorTypeChanged( int newType ) } QMessageBox::information(this, "Low Intensity Color Selection", "In the next window, select the low intensity color for the waterfall display", QMessageBox::Ok); lowIntensityColor = QColorDialog::getColor(lowIntensityColor, this); - + // Select the High Intensity Color highIntensityColor = _waterfallDisplayPlot->GetUserDefinedHighIntensityColor(); if(!highIntensityColor.isValid()){ @@ -691,5 +777,82 @@ void SpectrumDisplayForm::Waterfall3DIntensityColorTypeChanged( int newType ) QMessageBox::information(this, "High Intensity Color Selection", "In the next window, select the high intensity color for the waterfall display", QMessageBox::Ok); highIntensityColor = QColorDialog::getColor(highIntensityColor, this); } - _waterfall3DDisplayPlot->SetIntensityColorMapType(newType, lowIntensityColor, highIntensityColor); + _waterfall3DDisplayPlot->SetIntensityColorMapType(newType, lowIntensityColor, + highIntensityColor); +} + + +void +SpectrumDisplayForm::ToggleTabFrequency(const bool state) +{ + if(state == true) { + if(d_plot_fft == -1) { + SpectrumTypeTab->addTab(FrequencyPage, "Frequency Display"); + d_plot_fft = SpectrumTypeTab->count()-1; + } + } + else { + SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(FrequencyPage)); + d_plot_fft = -1; + } +} + +void +SpectrumDisplayForm::ToggleTabWaterfall(const bool state) +{ + if(state == true) { + if(d_plot_waterfall == -1) { + SpectrumTypeTab->addTab(WaterfallPage, "Waterfall Display"); + d_plot_waterfall = SpectrumTypeTab->count()-1; + } + } + else { + SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(WaterfallPage)); + d_plot_waterfall = -1; + } +} + +void +SpectrumDisplayForm::ToggleTabWaterfall3D(const bool state) +{ + if(state == true) { + if(d_plot_waterfall3d == -1) { + SpectrumTypeTab->addTab(Waterfall3DPage, "3D Waterfall Display"); + d_plot_waterfall3d = SpectrumTypeTab->count()-1; + } + } + else { + SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(Waterfall3DPage)); + d_plot_waterfall3d = -1; + } +} + +void +SpectrumDisplayForm::ToggleTabTime(const bool state) +{ + if(state == true) { + if(d_plot_time == -1) { + SpectrumTypeTab->addTab(TimeDomainPage, "Time Domain Display"); + d_plot_time = SpectrumTypeTab->count()-1; + } + } + else { + SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(TimeDomainPage)); + d_plot_time = -1; + } +} + +void +SpectrumDisplayForm::ToggleTabConstellation(const bool state) +{ + if(state == true) { + if(d_plot_constellation == -1) { + SpectrumTypeTab->addTab(ConstellationPage, "Constellation Display"); + d_plot_constellation = SpectrumTypeTab->count()-1; + } + } + else { + SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(ConstellationPage)); + d_plot_constellation = -1; + } } diff --git a/gr-qtgui/src/lib/spectrumdisplayform.h b/gr-qtgui/src/lib/spectrumdisplayform.h index 6e57e2ce..eba087bf 100644 --- a/gr-qtgui/src/lib/spectrumdisplayform.h +++ b/gr-qtgui/src/lib/spectrumdisplayform.h @@ -15,7 +15,7 @@ class SpectrumGUIClass; #include #include -class SpectrumDisplayForm : public QDialog, public Ui::SpectrumDisplayForm +class SpectrumDisplayForm : public QWidget, public Ui::SpectrumDisplayForm { Q_OBJECT @@ -23,13 +23,15 @@ class SpectrumDisplayForm : public QDialog, public Ui::SpectrumDisplayForm SpectrumDisplayForm(QWidget* parent = 0); ~SpectrumDisplayForm(); - void setSystem( SpectrumGUIClass * newSystem, const uint64_t numFFTDataPoints, const uint64_t numTimeDomainDataPoints ); + void setSystem( SpectrumGUIClass * newSystem, const uint64_t numFFTDataPoints, + const uint64_t numTimeDomainDataPoints ); int GetAverageCount(); void SetAverageCount( const int newCount ); void Reset(); void AverageDataReset(); - void ResizeBuffers( const uint64_t numFFTDataPoints, const uint64_t numTimeDomainDataPoints ); + void ResizeBuffers( const uint64_t numFFTDataPoints, + const uint64_t numTimeDomainDataPoints ); public slots: void resizeEvent( QResizeEvent * e ); @@ -40,7 +42,9 @@ public slots: void MinHoldResetBtn_clicked(); void MaxHoldResetBtn_clicked(); void PowerLineEdit_textChanged( const QString& valueString ); - void SetFrequencyRange( const double newStartFrequency, const double newStopFrequency, const double newCenterFrequency ); + void SetFrequencyRange( const double newStartFrequency, + const double newStopFrequency, + const double newCenterFrequency ); void closeEvent( QCloseEvent * e ); void WindowTypeChanged( int newItem ); void UseRFFrequenciesCB( bool useRFFlag ); @@ -54,6 +58,12 @@ public slots: void Waterfall3DAutoScaleBtnCB(); void FFTComboBoxSelectedCB(const QString&); + void ToggleTabFrequency(const bool state); + void ToggleTabWaterfall(const bool state); + void ToggleTabWaterfall3D(const bool state); + void ToggleTabTime(const bool state); + void ToggleTabConstellation(const bool state); + private slots: void newFrequencyData( const SpectrumUpdateEvent* ); @@ -84,6 +94,13 @@ private: double _peakAmplitude; static int _openGLWaterfall3DFlag; double _stopFrequency; + + // whether or not to use a particular display + int d_plot_fft; + int d_plot_waterfall; + int d_plot_waterfall3d; + int d_plot_time; + int d_plot_constellation; }; #endif /* SPECTRUM_DISPLAY_FORM_H */ diff --git a/gr-qtgui/src/lib/spectrumdisplayform.ui b/gr-qtgui/src/lib/spectrumdisplayform.ui index 561be64c..96096030 100644 --- a/gr-qtgui/src/lib/spectrumdisplayform.ui +++ b/gr-qtgui/src/lib/spectrumdisplayform.ui @@ -1,6 +1,6 @@ SpectrumDisplayForm - + 0 @@ -286,7 +286,7 @@ false - + 5 @@ -402,7 +402,7 @@ false - + 5 diff --git a/gr-qtgui/src/python/Makefile.am b/gr-qtgui/src/python/Makefile.am index ad578734..163b84a9 100644 --- a/gr-qtgui/src/python/Makefile.am +++ b/gr-qtgui/src/python/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004,2009 Free Software Foundation, Inc. +# Copyright 2008,2009 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,9 +21,12 @@ include $(top_srcdir)/Makefile.common -noinst_PYTHON = \ - qttest_f.py \ - qttest_c.py +noinst_PYTHON = \ + pyqt_example_f.py \ + pyqt_example.py \ + qt_digital.py \ + usrp2_display.py \ + usrp_display.py qtguipythondir = $(grpythondir)/qtgui diff --git a/gr-qtgui/src/python/pyqt_example.py b/gr-qtgui/src/python/pyqt_example.py new file mode 100755 index 00000000..27b949c8 --- /dev/null +++ b/gr-qtgui/src/python/pyqt_example.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python + +from gnuradio import gr, blks2 +from gnuradio.qtgui import qtgui +from PyQt4 import QtGui, QtCore +import sys, sip + +class dialog_box(QtGui.QWidget): + def __init__(self, display, control): + QtGui.QWidget.__init__(self, None) + self.setWindowTitle('PyQt Test GUI') + + self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self) + self.boxlayout.addWidget(display, 1) + self.boxlayout.addWidget(control) + + self.resize(800, 500) + +class control_box(QtGui.QWidget): + def __init__(self, parent=None): + QtGui.QWidget.__init__(self, parent) + self.setWindowTitle('Control Panel') + + self.setToolTip('Control the signals') + QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10)) + + self.layout = QtGui.QFormLayout(self) + + # Control the first signal + self.freq1Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 1 Frequency:", self.freq1Edit) + self.connect(self.freq1Edit, QtCore.SIGNAL("editingFinished()"), + self.freq1EditText) + + self.amp1Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 1 Amplitude:", self.amp1Edit) + self.connect(self.amp1Edit, QtCore.SIGNAL("editingFinished()"), + self.amp1EditText) + + + # Control the second signal + self.freq2Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 2 Frequency:", self.freq2Edit) + self.connect(self.freq2Edit, QtCore.SIGNAL("editingFinished()"), + self.freq2EditText) + + + self.amp2Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 2 Amplitude:", self.amp2Edit) + self.connect(self.amp2Edit, QtCore.SIGNAL("editingFinished()"), + self.amp2EditText) + + self.quit = QtGui.QPushButton('Close', self) + self.layout.addWidget(self.quit) + + self.connect(self.quit, QtCore.SIGNAL('clicked()'), + QtGui.qApp, QtCore.SLOT('quit()')) + + def attach_signal1(self, signal): + self.signal1 = signal + self.freq1Edit.setText(QtCore.QString("%1").arg(self.signal1.frequency())) + self.amp1Edit.setText(QtCore.QString("%1").arg(self.signal1.amplitude())) + + def attach_signal2(self, signal): + self.signal2 = signal + self.freq2Edit.setText(QtCore.QString("%1").arg(self.signal2.frequency())) + self.amp2Edit.setText(QtCore.QString("%1").arg(self.signal2.amplitude())) + + def freq1EditText(self): + try: + newfreq = float(self.freq1Edit.text()) + self.signal1.set_frequency(newfreq) + except ValueError: + print "Bad frequency value entered" + + def amp1EditText(self): + try: + newamp = float(self.amp1Edit.text()) + self.signal1.set_amplitude(newamp) + except ValueError: + print "Bad amplitude value entered" + + + def freq2EditText(self): + try: + newfreq = float(self.freq2Edit.text()) + self.signal2.set_frequency(newfreq) + except ValueError: + print "Bad frequency value entered" + + def amp2EditText(self): + try: + newamp = float(self.amp2Edit.text()) + self.signal2.set_amplitude(newamp) + except ValueError: + print "Bad amplitude value entered" + + +class my_top_block(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + Rs = 8000 + f1 = 1000 + f2 = 2000 + + fftsize = 2048 + + self.qapp = QtGui.QApplication(sys.argv) + + src1 = gr.sig_source_c(Rs, gr.GR_SIN_WAVE, f1, 0.1, 0) + src2 = gr.sig_source_c(Rs, gr.GR_SIN_WAVE, f2, 0.1, 0) + src = gr.add_cc() + channel = blks2.channel_model(0.001) + thr = gr.throttle(gr.sizeof_gr_complex, 100*fftsize) + self.snk1 = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, + -Rs/2, Rs/2, + "Complex Signal Example", + True, True, False, True, False) + + self.connect(src1, (src,0)) + self.connect(src2, (src,1)) + self.connect(src, channel, thr, self.snk1) + + self.ctrl_win = control_box() + self.ctrl_win.attach_signal1(src1) + self.ctrl_win.attach_signal2(src2) + + # Get the reference pointer to the SpectrumDisplayForm QWidget + pyQt = self.snk1.pyqwidget() + + # Wrap the pointer as a PyQt SIP object + # This can now be manipulated as a PyQt4.QtGui.QWidget + pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + + self.main_box = dialog_box(pyWin, self.ctrl_win) + + self.main_box.show() + +if __name__ == "__main__": + tb = my_top_block(); + tb.start() + tb.qapp.exec_() + diff --git a/gr-qtgui/src/python/pyqt_example_f.py b/gr-qtgui/src/python/pyqt_example_f.py new file mode 100755 index 00000000..bf10c5c0 --- /dev/null +++ b/gr-qtgui/src/python/pyqt_example_f.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python + +from gnuradio import gr, blks2 +from gnuradio.qtgui import qtgui +from PyQt4 import QtGui, QtCore +import sys, sip + +class dialog_box(QtGui.QWidget): + def __init__(self, display, control): + QtGui.QWidget.__init__(self, None) + self.setWindowTitle('PyQt Test GUI') + + self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self) + self.boxlayout.addWidget(display, 1) + self.boxlayout.addWidget(control) + + self.resize(800, 500) + +class control_box(QtGui.QWidget): + def __init__(self, parent=None): + QtGui.QWidget.__init__(self, parent) + self.setWindowTitle('Control Panel') + + self.setToolTip('Control the signals') + QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10)) + + self.layout = QtGui.QFormLayout(self) + + # Control the first signal + self.freq1Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 1 Frequency:", self.freq1Edit) + self.connect(self.freq1Edit, QtCore.SIGNAL("editingFinished()"), + self.freq1EditText) + + self.amp1Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 1 Amplitude:", self.amp1Edit) + self.connect(self.amp1Edit, QtCore.SIGNAL("editingFinished()"), + self.amp1EditText) + + + # Control the second signal + self.freq2Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 2 Frequency:", self.freq2Edit) + self.connect(self.freq2Edit, QtCore.SIGNAL("editingFinished()"), + self.freq2EditText) + + + self.amp2Edit = QtGui.QLineEdit(self) + self.layout.addRow("Signal 2 Amplitude:", self.amp2Edit) + self.connect(self.amp2Edit, QtCore.SIGNAL("editingFinished()"), + self.amp2EditText) + + self.quit = QtGui.QPushButton('Close', self) + self.layout.addWidget(self.quit) + + self.connect(self.quit, QtCore.SIGNAL('clicked()'), + QtGui.qApp, QtCore.SLOT('quit()')) + + def attach_signal1(self, signal): + self.signal1 = signal + self.freq1Edit.setText(QtCore.QString("%1").arg(self.signal1.frequency())) + self.amp1Edit.setText(QtCore.QString("%1").arg(self.signal1.amplitude())) + + def attach_signal2(self, signal): + self.signal2 = signal + self.freq2Edit.setText(QtCore.QString("%1").arg(self.signal2.frequency())) + self.amp2Edit.setText(QtCore.QString("%1").arg(self.signal2.amplitude())) + + def freq1EditText(self): + try: + newfreq = float(self.freq1Edit.text()) + self.signal1.set_frequency(newfreq) + except ValueError: + print "Bad frequency value entered" + + def amp1EditText(self): + try: + newamp = float(self.amp1Edit.text()) + self.signal1.set_amplitude(newamp) + except ValueError: + print "Bad amplitude value entered" + + + def freq2EditText(self): + try: + newfreq = float(self.freq2Edit.text()) + self.signal2.set_frequency(newfreq) + except ValueError: + print "Bad frequency value entered" + + def amp2EditText(self): + try: + newamp = float(self.amp2Edit.text()) + self.signal2.set_amplitude(newamp) + except ValueError: + print "Bad amplitude value entered" + + +class my_top_block(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + Rs = 8000 + f1 = 1000 + f2 = 2000 + + fftsize = 2048 + + self.qapp = QtGui.QApplication(sys.argv) + + src1 = gr.sig_source_f(Rs, gr.GR_SIN_WAVE, f1, 0.1, 0) + src2 = gr.sig_source_f(Rs, gr.GR_SIN_WAVE, f2, 0.1, 0) + src = gr.add_ff() + thr = gr.throttle(gr.sizeof_float, 100*fftsize) + self.snk1 = qtgui.sink_f(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, + -Rs/2, Rs/2, + "Float Signal Example", + True, True, False, True, False) + + self.connect(src1, (src,0)) + self.connect(src2, (src,1)) + self.connect(src, thr, self.snk1) + + self.ctrl_win = control_box() + self.ctrl_win.attach_signal1(src1) + self.ctrl_win.attach_signal2(src2) + + # Get the reference pointer to the SpectrumDisplayForm QWidget + pyQt = self.snk1.pyqwidget() + + # Wrap the pointer as a PyQt SIP object + # This can now be manipulated as a PyQt4.QtGui.QWidget + pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + + self.main_box = dialog_box(pyWin, self.ctrl_win) + + self.main_box.show() + +if __name__ == "__main__": + tb = my_top_block(); + tb.start() + tb.qapp.exec_() + diff --git a/gr-qtgui/src/python/qt_digital.py b/gr-qtgui/src/python/qt_digital.py index f7635b4a..55be56b1 100755 --- a/gr-qtgui/src/python/qt_digital.py +++ b/gr-qtgui/src/python/qt_digital.py @@ -2,12 +2,109 @@ from gnuradio import gr, blks2 from gnuradio.qtgui import qtgui +from PyQt4 import QtGui, QtCore +import sys, sip import scipy +class dialog_box(QtGui.QWidget): + def __init__(self, display_tx, display_rx, channel): + QtGui.QWidget.__init__(self, None) + self.setWindowTitle('Digital Signal Examples') + + self.control = control_panel(channel, self) + + hlayout = QtGui.QHBoxLayout() + hlayout.addWidget(display_tx) + hlayout.addWidget(display_rx) + hlayout.setGeometry(QtCore.QRect(0,0,100,100)) + + vlayout = QtGui.QVBoxLayout() + vlayout.addLayout(hlayout) + vlayout.addLayout(self.control.layout, -1) + #vlayout.addStretch(-1) + + self.setLayout(vlayout) + self.resize(1000, 1000) + +class control_panel(QtGui.QWidget): + def __init__(self, channel, parent=None): + QtGui.QWidget.__init__(self, parent) + self.setWindowTitle('Control Panel') + + self.channel = channel + + self.layout = QtGui.QFormLayout() + + # Set channel noise + self.noiseEdit = QtGui.QLineEdit(self) + self.layout.addRow("Noise Amplitude:", self.noiseEdit) + self.connect(self.noiseEdit, QtCore.SIGNAL("editingFinished()"), + self.noiseEditText) + + # Set channel frequency offset + self.freqEdit = QtGui.QLineEdit(self) + self.layout.addRow("Frequency Offset:", self.freqEdit) + self.connect(self.freqEdit, QtCore.SIGNAL("editingFinished()"), + self.freqEditText) + + # Set channel timing offset + self.timeEdit = QtGui.QLineEdit(self) + self.layout.addRow("Timing Offset:", self.timeEdit) + self.connect(self.timeEdit, QtCore.SIGNAL("editingFinished()"), + self.timeEditText) + + self.quit = QtGui.QPushButton('Close', self) + self.layout.addRow(self.quit) + + self.connect(self.quit, QtCore.SIGNAL('clicked()'), + QtGui.qApp, QtCore.SLOT('quit()')) + + def set_noise(self, noise): + self.noise = noise + self.noiseEdit.setText(QtCore.QString("%1").arg(self.noise)) + + def set_frequency(self, freq): + self.freq = freq + self.freqEdit.setText(QtCore.QString("%1").arg(self.freq)) + + def set_time_offset(self, to): + self.timing_offset = to + self.timeEdit.setText(QtCore.QString("%1").arg(self.timing_offset)) + + def noiseEditText(self): + try: + noise = self.noiseEdit.text().toDouble()[0] + self.channel.noise.set_amplitude(noise) + + self.noise = noise + except RuntimeError: + pass + + def freqEditText(self): + try: + freq = self.freqEdit.text().toDouble()[0] + self.channel.freq_offset.set_frequency(freq) + + self.freq = freq + except RuntimeError: + pass + + def timeEditText(self): + try: + to = self.timeEdit.text().toDouble()[0] + self.channel.timing_offset.set_interp_ratio(to) + + self.timing_offset = to + except RuntimeError: + pass + + class my_top_block(gr.top_block): def __init__(self): gr.top_block.__init__(self) + self.qapp = QtGui.QApplication(sys.argv) + sps = 2 excess_bw = 0.35 gray_code = True @@ -20,21 +117,36 @@ class my_top_block(gr.top_block): rrctaps = gr.firdes.root_raised_cosine(1, sps, 1, excess_bw, 21) rx_rrc = gr.fir_filter_ccf(sps, rrctaps) - + + noise = 1e-7 + fo = 1e-6 + to = 1.0 + channel = blks2.channel_model(noise, fo, to) + thr = gr.throttle(gr.sizeof_gr_complex, 10*fftsize) - self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -1/2, 1/2) - self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -1/2, 1/2) + self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -1/2, 1/2, + "Tx", True, True, False, True, True) + + self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -1/2, 1/2, + "Rx", True, True, False, True, True) - self.connect(src, mod, self.snk_tx) - self.connect(mod, rx_rrc, thr, self.snk_rx) + self.connect(src, mod, channel, self.snk_tx) + self.connect(channel, rx_rrc, thr, self.snk_rx) - self.snk_tx.initialize() - qapp = self.snk_tx.get_qapplication() - self.snk_rx.initialize(qapp) + pyTxQt = self.snk_tx.pyqwidget() + pyTx = sip.wrapinstance(pyTxQt, QtGui.QWidget) + pyRxQt = self.snk_rx.pyqwidget() + pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget) + + self.main_box = dialog_box(pyTx, pyRx, channel) + self.main_box.control.set_noise(noise) + self.main_box.control.set_frequency(fo) + self.main_box.control.set_time_offset(to) + + self.main_box.show() + if __name__ == "__main__": tb = my_top_block(); tb.start() - tb.snk_tx.start_app(); - #tb.wait(); - + tb.qapp.exec_() diff --git a/gr-qtgui/src/python/qttest_c.py b/gr-qtgui/src/python/qttest_c.py deleted file mode 100755 index c681c84a..00000000 --- a/gr-qtgui/src/python/qttest_c.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr -from gnuradio.qtgui import qtgui - -class my_top_block(gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - - Rs = 8000 - f1 = 1000 - f2 = 2000 - - fftsize = 2048 - - src1 = gr.sig_source_c(Rs, gr.GR_SIN_WAVE, f1, 0.1, 0) - src2 = gr.sig_source_c(Rs, gr.GR_SIN_WAVE, f2, 0.1, 0) - src = gr.add_cc() - thr = gr.throttle(gr.sizeof_gr_complex, 20*fftsize) - self.snk1 = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -Rs/2, Rs/2) - self.snk2 = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -Rs/2, Rs/2) - - self.connect(src1, (src,0)) - self.connect(src2, (src,1)) - self.connect(src, thr, self.snk1) - self.connect(src1, self.snk2) - - self.snk1.initialize() - qapp = self.snk1.get_qapplication() - self.snk2.initialize(qapp) - -if __name__ == "__main__": - tb = my_top_block(); - tb.start() - tb.snk1.start_app(); - #tb.wait(); - diff --git a/gr-qtgui/src/python/qttest_f.py b/gr-qtgui/src/python/qttest_f.py deleted file mode 100755 index a950b35b..00000000 --- a/gr-qtgui/src/python/qttest_f.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr -from gnuradio.qtgui import qtgui - -class my_top_block(gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - - fftsize = 8192 - - win = gr.firdes.window(gr.firdes.WIN_HANN, fftsize, 0) - - src1 = gr.sig_source_f(1, gr.GR_SIN_WAVE, 0.1, 0.1, 0) - src2 = gr.sig_source_f(1, gr.GR_SIN_WAVE, 0.015, 0.1, 0) - src = gr.add_ff() - thr = gr.throttle(gr.sizeof_float, 20*fftsize) - self.snk = qtgui.sink_f(fftsize, win, -0.5, 0.5) - - self.connect(src1, (src,0)) - self.connect(src2, (src,1)) - self.connect(src, thr, self.snk) - -if __name__ == "__main__": - tb = my_top_block(); - tb.start() - tb.snk.start_app(); - #tb.wait(); - diff --git a/gr-qtgui/src/python/usrp2_display.py b/gr-qtgui/src/python/usrp2_display.py new file mode 100755 index 00000000..e5f01ef0 --- /dev/null +++ b/gr-qtgui/src/python/usrp2_display.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python +# +# Copyright 2009 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, gru +from gnuradio import usrp2 +from gnuradio import eng_notation +from gnuradio.eng_option import eng_option +from gnuradio.qtgui import qtgui +from optparse import OptionParser +from PyQt4 import QtGui, QtCore +import sys, sip + +class dialog_box(QtGui.QWidget): + def __init__(self, display, control): + QtGui.QWidget.__init__(self, None) + self.setWindowTitle('USRP2 Display') + + self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self) + self.boxlayout.addWidget(display, 1) + self.boxlayout.addWidget(control) + + self.resize(800, 500) + +class control_panel(QtGui.QWidget): + def __init__(self, usrp, qtsink, parent=None): + QtGui.QWidget.__init__(self, parent) + self.setWindowTitle('USRP2 Control Panel') + + self.usrp = usrp + self.qtsink = qtsink + self.adc_rate = self.usrp.adc_rate() + + self.freq = 0 + self.decim = 0 + self.bw = 0 + self.gain = 0 + + self.setToolTip('Set the values of the USRP2') + QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10)) + + self.layout = QtGui.QFormLayout(self) + + # Received frequency + self.freqEdit = QtGui.QLineEdit(self) + self.layout.addRow("Frequency:", self.freqEdit) + self.connect(self.freqEdit, QtCore.SIGNAL("editingFinished()"), + self.freqEditText) + + # Receiver gain + self.gainEdit = QtGui.QLineEdit(self) + self.layout.addRow("Gain:", self.gainEdit) + self.connect(self.gainEdit, QtCore.SIGNAL("editingFinished()"), + self.gainEditText) + + + # Decim / Bandwidth + self.decimEdit = QtGui.QLineEdit(self) + self.layout.addRow("Decim Rate:", self.decimEdit) + self.connect(self.decimEdit, QtCore.SIGNAL("editingFinished()"), + self.decimEditText) + + self.quit = QtGui.QPushButton('Close', self) + self.layout.addRow(self.quit) + + self.connect(self.quit, QtCore.SIGNAL('clicked()'), + QtGui.qApp, QtCore.SLOT('quit()')) + + def set_frequency(self, freq): + self.freq = freq + sfreq = eng_notation.num_to_str(self.freq) + self.freqEdit.setText(QtCore.QString("%1").arg(sfreq)) + + def set_gain(self, gain): + self.gain = gain + self.gainEdit.setText(QtCore.QString("%1").arg(self.gain)) + + def set_decim(self, decim): + self.decim = decim + self.bw = self.adc_rate / float(self.decim) / 1000.0 + self.decimEdit.setText(QtCore.QString("%1").arg(self.decim)) + + def freqEditText(self): + try: + freq = eng_notation.str_to_num(self.freqEdit.text().toAscii()) + r = self.usrp.set_center_freq(freq) + self.freq = freq + self.qtsink.set_frequency_range(self.freq, self.freq-self.bw/2.0, self.freq+self.bw/2.0) + except RuntimeError: + pass + + #self.set_frequency(self.freq) + + def gainEditText(self): + try: + gain = float(self.gainEdit.text()) + self.usrp.set_gain(gain) + self.gain = gain + except ValueError: + pass + + #self.set_gain(gain) + + def decimEditText(self): + try: + decim = int(self.decimEdit.text()) + self.usrp.set_decim(decim) + + self.decim = decim + self.bw = self.adc_rate / self.decim + self.qtsink.set_frequency_range(-self.bw/2.0, self.bw/2.0, self.freq) + + except ValueError: + pass + + #self.set_decim(decim) + +class app_top_block(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + parser = OptionParser(option_class=eng_option) + parser.add_option("-e", "--interface", type="string", default="eth0", + help="select Ethernet interface, default is eth0") + parser.add_option("-m", "--mac-addr", type="string", default="", + help="select USRP by MAC address, default is auto-select") + parser.add_option("-d", "--decim", type="int", default=16, + help="set fgpa decimation rate to DECIM [default=%default]") + parser.add_option("-f", "--freq", type="eng_float", default=None, + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB (default is midpoint)") + parser.add_option("--fft-size", type="int", default=1024, + help="Set number of FFT bins [default=%default]") + (options, args) = parser.parse_args() + + if len(args) != 0: + parser.print_help() + sys.exit(1) + self.options = options + self.show_debug_info = True + + self.qapp = QtGui.QApplication(sys.argv) + + self.u = usrp2.source_32fc(options.interface, options.mac_addr) + self.u.set_decim(options.decim) + + input_rate = self.u.adc_rate() / self.u.decim() + + self.snk = qtgui.sink_c(options.fft_size, gr.firdes.WIN_BLACKMAN_hARRIS, + -input_rate/2, input_rate/2, + "USRP2 Display", + True, True, False, True, False) + + self.connect(self.u, self.snk) + + if options.gain is None: + # if no gain was specified, use the mid-point in dB + g = self.u.gain_range() + options.gain = float(g[0]+g[1])/2 + + if options.freq is None: + # if no freq was specified, use the mid-point + r = self.u.freq_range() + options.freq = float(r[0]+r[1])/2 + + self.set_gain(options.gain) + r = self.u.set_center_freq(options.freq) + + if self.show_debug_info: + print "Decimation rate: ", self.u.decim() + print "Bandwidth: ", input_rate + print "D'board: ", self.u.daughterboard_id() + + + self.ctrl_win = control_panel(self.u, self.snk) + + self.ctrl_win.set_frequency(options.freq) + self.ctrl_win.set_gain(options.gain) + self.ctrl_win.set_decim(options.decim) + + # Get the reference pointer to the SpectrumDisplayForm QWidget + pyQt = self.snk.pyqwidget() + + # Wrap the pointer as a PyQt SIP object + # This can now be manipulated as a PyQt4.QtGui.QWidget + pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + + self.main_box = dialog_box(pyWin, self.ctrl_win) + + self.main_box.show() + + def set_gain(self, gain): + self.u.set_gain(gain) + + def set_decim(self, decim): + ok = self.u.set_decim(decim) + if not ok: + print "set_decim failed" + input_rate = self.u.adc_rate() / self.u.decim() + return ok + +def main (): + tb = app_top_block() + tb.start() + tb.snk.exec_(); + +if __name__ == '__main__': + try: + main () + except KeyboardInterrupt: + pass + diff --git a/gr-qtgui/src/python/usrp_display.py b/gr-qtgui/src/python/usrp_display.py new file mode 100755 index 00000000..d5d2bc67 --- /dev/null +++ b/gr-qtgui/src/python/usrp_display.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python + +from gnuradio import gr +from gnuradio import usrp +from gnuradio import eng_notation +from gnuradio.eng_option import eng_option +from gnuradio.qtgui import qtgui +from optparse import OptionParser +from PyQt4 import QtGui, QtCore +import sys, sip + +class dialog_box(QtGui.QWidget): + def __init__(self, display, control): + QtGui.QWidget.__init__(self, None) + self.setWindowTitle('USRP FFT') + + self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self) + self.boxlayout.addWidget(display, 1) + self.boxlayout.addWidget(control) + + self.resize(800, 500) + +class control_panel(QtGui.QWidget): + def __init__(self, usrp, subdev, qtsink, parent=None): + QtGui.QWidget.__init__(self, parent) + self.setWindowTitle('USRP Control Panel') + + self.usrp = usrp + self.subdev = subdev + self.qtsink = qtsink + self.adc_rate = self.usrp.converter_rate() + + self.freq = 0 + self.decim = 0 + self.bw = 0 + self.gain = 0 + + self.setToolTip('Set the values of the USRP') + QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10)) + + self.layout = QtGui.QFormLayout(self) + + # Received frequency + self.freqEdit = QtGui.QLineEdit(self) + self.layout.addRow("Frequency:", self.freqEdit) + self.connect(self.freqEdit, QtCore.SIGNAL("editingFinished()"), + self.freqEditText) + + # Receiver gain + self.gainEdit = QtGui.QLineEdit(self) + self.layout.addRow("Gain:", self.gainEdit) + self.connect(self.gainEdit, QtCore.SIGNAL("editingFinished()"), + self.gainEditText) + + + # Decim / Bandwidth + self.decimEdit = QtGui.QLineEdit(self) + self.layout.addRow("Decim Rate:", self.decimEdit) + self.connect(self.decimEdit, QtCore.SIGNAL("editingFinished()"), + self.decimEditText) + + self.quit = QtGui.QPushButton('Close', self) + self.layout.addRow(self.quit) + + self.connect(self.quit, QtCore.SIGNAL('clicked()'), + QtGui.qApp, QtCore.SLOT('quit()')) + + def set_frequency(self, freq): + self.freq = freq + sfreq = eng_notation.num_to_str(self.freq) + self.freqEdit.setText(QtCore.QString("%1").arg(sfreq)) + + def set_gain(self, gain): + self.gain = gain + self.gainEdit.setText(QtCore.QString("%1").arg(self.gain)) + + def set_decim(self, decim): + self.decim = decim + self.bw = self.adc_rate / float(self.decim) / 1000.0 + self.decimEdit.setText(QtCore.QString("%1").arg(self.decim)) + + def freqEditText(self): + try: + freq = eng_notation.str_to_num(self.freqEdit.text().toAscii()) + self.usrp.tune(0, self.subdev, freq) + self.freq = freq + self.qtsink.set_frequency_range(self.freq, self.freq-self.bw/2.0, self.freq+self.bw/2.0) + except RuntimeError: + pass + + #self.set_frequency(self.freq) + + def gainEditText(self): + try: + gain = float(self.gainEdit.text()) + self.subdev.set_gain(gain) + self.gain = gain + except ValueError: + pass + + #self.set_gain(gain) + + def decimEditText(self): + try: + decim = int(self.decimEdit.text()) + self.usrp.set_decim_rate(decim) + + self.decim = decim + self.bw = self.adc_rate / self.decim + self.qtsink.set_frequency_range(-self.bw/2.0, self.bw/2.0, self.freq) + + except ValueError: + pass + + #self.set_decim(decim) + + +class my_top_block(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + parser = OptionParser(option_class=eng_option) + parser.add_option("-w", "--which", type="int", default=0, + help="select which USRP (0, 1, ...) default is %default", + metavar="NUM") + parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, + help="select USRP Rx side A or B (default=first one with a daughterboard)") + parser.add_option("-A", "--antenna", default=None, + help="select Rx Antenna (only on RFX-series boards)") + parser.add_option("-d", "--decim", type="int", default=16, + help="set fgpa decimation rate to DECIM [default=%default]") + parser.add_option("-f", "--freq", type="eng_float", default=None, + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB [default is midpoint]") + parser.add_option("-W", "--waterfall", action="store_true", default=False, + help="Enable waterfall display") + parser.add_option("-8", "--width-8", action="store_true", default=False, + help="Enable 8-bit samples across USB") + parser.add_option( "--no-hb", action="store_true", default=False, + help="don't use halfband filter in usrp") + parser.add_option("-S", "--oscilloscope", action="store_true", default=False, + help="Enable oscilloscope display") + parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1, + help="Set fftsink averaging factor, [default=%default]") + parser.add_option("", "--ref-scale", type="eng_float", default=13490.0, + help="Set dBFS=0dB input value, [default=%default]") + parser.add_option("", "--fft-size", type="int", default=1024, + help="Set FFT frame size, [default=%default]"); + + (options, args) = parser.parse_args() + if len(args) != 0: + parser.print_help() + sys.exit(1) + self.options = options + self.show_debug_info = True + + # Call this before creating the Qt sink + self.qapp = QtGui.QApplication(sys.argv) + + self.u = usrp.source_c(which=options.which, decim_rate=options.decim) + rx_subdev_spec = (0,0) + self.u.set_mux(usrp.determine_rx_mux_value(self.u, rx_subdev_spec)) + self.subdev = usrp.selected_subdev(self.u, rx_subdev_spec) + + if options.gain is None: + # if no gain was specified, use the mid-point in dB + g = self.subdev.gain_range() + options.gain = float(g[0]+g[1])/2 + self.subdev.set_gain(options.gain) + + if options.freq is None: + # if no frequency was specified, use the mid-point of the subdev + f = self.subdev.freq_range() + options.freq = float(f[0]+f[1])/2 + self.u.tune(0, self.subdev, options.freq) + + fftsize = 2048 + input_rate = self.u.converter_rate() / self.u.decim_rate() + self.snk = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, + -input_rate/2, input_rate/2, + "USRP Display", + True, True, False, True, False) + + amp = gr.multiply_const_cc(0.001) + self.connect(self.u, amp, self.snk) + + self.ctrl_win = control_panel(self.u, self.subdev, self.snk) + + self.ctrl_win.set_frequency(options.freq) + self.ctrl_win.set_gain(options.gain) + self.ctrl_win.set_decim(options.decim) + + # Get the reference pointer to the SpectrumDisplayForm QWidget + pyQt = self.snk.pyqwidget() + + # Wrap the pointer as a PyQt SIP object + # This can now be manipulated as a PyQt4.QtGui.QWidget + pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) + + self.main_box = dialog_box(pyWin, self.ctrl_win) + + self.main_box.show() + +if __name__ == "__main__": + tb = my_top_block(); + tb.start() + tb.qapp.exec_() -- 2.30.2