summaryrefslogtreecommitdiff
path: root/gr-qtgui/lib/SpectrumGUIClass.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gr-qtgui/lib/SpectrumGUIClass.cc')
-rw-r--r--gr-qtgui/lib/SpectrumGUIClass.cc478
1 files changed, 478 insertions, 0 deletions
diff --git a/gr-qtgui/lib/SpectrumGUIClass.cc b/gr-qtgui/lib/SpectrumGUIClass.cc
new file mode 100644
index 000000000..3efba3f40
--- /dev/null
+++ b/gr-qtgui/lib/SpectrumGUIClass.cc
@@ -0,0 +1,478 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SPECTRUM_GUI_CLASS_CPP
+#define SPECTRUM_GUI_CLASS_CPP
+
+#include <SpectrumGUIClass.h>
+//Added by qt3to4:
+#include <QEvent>
+#include <QCustomEvent>
+
+const long SpectrumGUIClass::MAX_FFT_SIZE = 32768;
+const long SpectrumGUIClass::MIN_FFT_SIZE = 256;
+
+SpectrumGUIClass::SpectrumGUIClass(const uint64_t maxDataSize,
+ const uint64_t fftSize,
+ const double newCenterFrequency,
+ const double newStartFrequency,
+ const double newStopFrequency)
+{
+ _dataPoints = maxDataSize;
+ if(_dataPoints < 2){
+ _dataPoints = 2;
+ }
+ _lastDataPointCount = _dataPoints;
+
+ _fftSize = fftSize;
+
+ _pendingGUIUpdateEventsCount = 0;
+ _droppedEntriesCount = 0;
+
+ _centerFrequency = newCenterFrequency;
+ _startFrequency = newStartFrequency;
+ _stopFrequency = newStopFrequency;
+
+ _windowType = 5;
+
+ _lastGUIUpdateTime = 0;
+
+ _windowOpennedFlag = false;
+ _fftBuffersCreatedFlag = false;
+
+ _powerValue = 1;
+}
+
+SpectrumGUIClass::~SpectrumGUIClass()
+{
+ // We don't need to delete this since as a QWidget, it is supposed to be destroyed
+ // with it's parent. Deleting it causes a segmentation fault, and not deleting it
+ // does not leave any extra memory.
+ //if(GetWindowOpenFlag()){
+ //delete _spectrumDisplayForm;
+ //}
+
+ if(_fftBuffersCreatedFlag){
+ delete[] _fftPoints;
+ delete[] _realTimeDomainPoints;
+ delete[] _imagTimeDomainPoints;
+ }
+}
+
+void
+SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent,
+ const bool frequency, const bool waterfall,
+ const bool time, const bool constellation)
+{
+ d_mutex.lock();
+
+ if(!_windowOpennedFlag){
+
+ if(!_fftBuffersCreatedFlag){
+ _fftPoints = new std::complex<float>[_dataPoints];
+ _realTimeDomainPoints = new double[_dataPoints];
+ _imagTimeDomainPoints = new double[_dataPoints];
+ _fftBuffersCreatedFlag = true;
+
+
+ memset(_fftPoints, 0x0, _dataPoints*sizeof(std::complex<float>));
+ memset(_realTimeDomainPoints, 0x0, _dataPoints*sizeof(double));
+ memset(_imagTimeDomainPoints, 0x0, _dataPoints*sizeof(double));
+ }
+
+ // Called from the Event Thread
+ _spectrumDisplayForm = new SpectrumDisplayForm(parent);
+
+ // Toggle Windows on/off
+ _spectrumDisplayForm->ToggleTabFrequency(frequency);
+ _spectrumDisplayForm->ToggleTabWaterfall(waterfall);
+ _spectrumDisplayForm->ToggleTabTime(time);
+ _spectrumDisplayForm->ToggleTabConstellation(constellation);
+
+ _windowOpennedFlag = true;
+
+ _spectrumDisplayForm->setSystem(this, _dataPoints, _fftSize);
+
+ qApp->processEvents();
+ }
+ d_mutex.unlock();
+
+
+ SetDisplayTitle(_title);
+ Reset();
+
+ qApp->postEvent(_spectrumDisplayForm,
+ new QEvent(QEvent::Type(QEvent::User+3)));
+
+ _lastGUIUpdateTime = 0;
+
+ // Draw Blank Display
+ UpdateWindow(false, NULL, 0, NULL, 0, NULL, 0, gruel::high_res_timer_now(), true);
+
+ // Set up the initial frequency axis settings
+ SetFrequencyRange(_centerFrequency, _startFrequency, _stopFrequency);
+
+ // GUI Thread only
+ qApp->processEvents();
+
+ // Set the FFT Size combo box to display the right number
+ int idx = _spectrumDisplayForm->FFTSizeComboBox->findText(QString("%1").arg(_fftSize));
+ _spectrumDisplayForm->FFTSizeComboBox->setCurrentIndex(idx);
+}
+
+void
+SpectrumGUIClass::Reset()
+{
+ if(GetWindowOpenFlag()) {
+ qApp->postEvent(_spectrumDisplayForm,
+ new SpectrumFrequencyRangeEvent(_centerFrequency,
+ _startFrequency,
+ _stopFrequency));
+ qApp->postEvent(_spectrumDisplayForm, new SpectrumWindowResetEvent());
+ }
+ _droppedEntriesCount = 0;
+ // Call the following function the the Spectrum Window Reset Event window
+ // ResetPendingGUIUpdateEvents();
+}
+
+void
+SpectrumGUIClass::SetDisplayTitle(const std::string newString)
+{
+ _title.assign(newString);
+
+ if(GetWindowOpenFlag()){
+ qApp->postEvent(_spectrumDisplayForm,
+ new SpectrumWindowCaptionEvent(_title.c_str()));
+ }
+}
+
+bool
+SpectrumGUIClass::GetWindowOpenFlag()
+{
+ gruel::scoped_lock lock(d_mutex);
+ bool returnFlag = false;
+ returnFlag = _windowOpennedFlag;
+ return returnFlag;
+}
+
+
+void
+SpectrumGUIClass::SetWindowOpenFlag(const bool newFlag)
+{
+ gruel::scoped_lock lock(d_mutex);
+ _windowOpennedFlag = newFlag;
+}
+
+void
+SpectrumGUIClass::SetFrequencyRange(const double centerFreq,
+ const double startFreq,
+ const double stopFreq)
+{
+ gruel::scoped_lock lock(d_mutex);
+ _centerFrequency = centerFreq;
+ _startFrequency = startFreq;
+ _stopFrequency = stopFreq;
+
+ _spectrumDisplayForm->SetFrequencyRange(_centerFrequency,
+ _startFrequency,
+ _stopFrequency);
+}
+
+double
+SpectrumGUIClass::GetStartFrequency()
+{
+ gruel::scoped_lock lock(d_mutex);
+ double returnValue = 0.0;
+ returnValue = _startFrequency;
+ return returnValue;
+}
+
+double
+SpectrumGUIClass::GetStopFrequency()
+{
+ gruel::scoped_lock lock(d_mutex);
+ double returnValue = 0.0;
+ returnValue = _stopFrequency;
+ return returnValue;
+}
+
+double
+SpectrumGUIClass::GetCenterFrequency()
+{
+ gruel::scoped_lock lock(d_mutex);
+ double returnValue = 0.0;
+ returnValue = _centerFrequency;
+ return returnValue;
+}
+
+
+void
+SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag,
+ const std::complex<float>* fftBuffer,
+ const uint64_t inputBufferSize,
+ const float* realTimeDomainData,
+ const uint64_t realTimeDomainDataSize,
+ const float* complexTimeDomainData,
+ const uint64_t complexTimeDomainDataSize,
+ const gruel::high_res_timer_type timestamp,
+ const bool lastOfMultipleFFTUpdateFlag)
+{
+ //gruel::scoped_lock lock(d_mutex);
+ int64_t bufferSize = inputBufferSize;
+ bool repeatDataFlag = false;
+ if(bufferSize > _dataPoints){
+ bufferSize = _dataPoints;
+ }
+ int64_t timeDomainBufferSize = 0;
+
+ if(updateDisplayFlag){
+ if((fftBuffer != NULL) && (bufferSize > 0)){
+ memcpy(_fftPoints, fftBuffer, bufferSize * sizeof(std::complex<float>));
+ }
+
+ // Can't do a memcpy since ths is going from float to double data type
+ if((realTimeDomainData != NULL) && (realTimeDomainDataSize > 0)){
+ const float* realTimeDomainDataPtr = realTimeDomainData;
+
+ double* realTimeDomainPointsPtr = _realTimeDomainPoints;
+ timeDomainBufferSize = realTimeDomainDataSize;
+
+ memset( _imagTimeDomainPoints, 0x0, realTimeDomainDataSize*sizeof(double));
+ for( uint64_t number = 0; number < realTimeDomainDataSize; number++){
+ *realTimeDomainPointsPtr++ = *realTimeDomainDataPtr++;
+ }
+ }
+
+ // Can't do a memcpy since ths is going from float to double data type
+ if((complexTimeDomainData != NULL) && (complexTimeDomainDataSize > 0)){
+ const float* complexTimeDomainDataPtr = complexTimeDomainData;
+
+ double* realTimeDomainPointsPtr = _realTimeDomainPoints;
+ double* imagTimeDomainPointsPtr = _imagTimeDomainPoints;
+
+ timeDomainBufferSize = complexTimeDomainDataSize;
+ for( uint64_t number = 0; number < complexTimeDomainDataSize; number++){
+ *realTimeDomainPointsPtr++ = *complexTimeDomainDataPtr++;
+ *imagTimeDomainPointsPtr++ = *complexTimeDomainDataPtr++;
+ }
+ }
+ }
+
+ // If bufferSize is zero, then just update the display by sending over the old data
+ if(bufferSize < 1){
+ bufferSize = _lastDataPointCount;
+ repeatDataFlag = true;
+ }
+ else{
+ // Since there is data this time, update the count
+ _lastDataPointCount = bufferSize;
+ }
+
+ const gruel::high_res_timer_type currentTime = gruel::high_res_timer_now();
+ const gruel::high_res_timer_type lastUpdateGUITime = GetLastGUIUpdateTime();
+
+ if((currentTime - lastUpdateGUITime > (4*_updateTime)*gruel::high_res_timer_tps()) &&
+ (GetPendingGUIUpdateEvents() > 0) && lastUpdateGUITime != 0) {
+ // 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,
+ 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
+ if(!repeatDataFlag){
+ _droppedEntriesCount = 0;
+ }
+ }
+}
+
+float
+SpectrumGUIClass::GetPowerValue()
+{
+ gruel::scoped_lock lock(d_mutex);
+ float returnValue = 0;
+ returnValue = _powerValue;
+ return returnValue;
+}
+
+void
+SpectrumGUIClass::SetPowerValue(const float value)
+{
+ gruel::scoped_lock lock(d_mutex);
+ _powerValue = value;
+}
+
+int
+SpectrumGUIClass::GetWindowType()
+{
+ gruel::scoped_lock lock(d_mutex);
+ int returnValue = 0;
+ returnValue = _windowType;
+ return returnValue;
+}
+
+void
+SpectrumGUIClass::SetWindowType(const int newType)
+{
+ gruel::scoped_lock lock(d_mutex);
+ _windowType = newType;
+}
+
+int
+SpectrumGUIClass::GetFFTSize()
+{
+ int returnValue = 0;
+ returnValue = _fftSize;
+ return returnValue;
+}
+
+int
+SpectrumGUIClass::GetFFTSizeIndex()
+{
+ gruel::scoped_lock lock(d_mutex);
+ int fftsize = GetFFTSize();
+ switch(fftsize) {
+ case(1024): return 0; break;
+ case(2048): return 1; break;
+ case(4096): return 2; break;
+ case(8192): return 3; break;
+ case(16384): return 3; break;
+ case(32768): return 3; break;
+ default: return 0;
+ }
+}
+
+void
+SpectrumGUIClass::SetFFTSize(const int newSize)
+{
+ gruel::scoped_lock lock(d_mutex);
+ _fftSize = newSize;
+}
+
+gruel::high_res_timer_type
+SpectrumGUIClass::GetLastGUIUpdateTime()
+{
+ gruel::scoped_lock lock(d_mutex);
+ gruel::high_res_timer_type returnValue;
+ returnValue = _lastGUIUpdateTime;
+ return returnValue;
+}
+
+void
+SpectrumGUIClass::SetLastGUIUpdateTime(const gruel::high_res_timer_type newTime)
+{
+ gruel::scoped_lock lock(d_mutex);
+ _lastGUIUpdateTime = newTime;
+}
+
+unsigned int
+SpectrumGUIClass::GetPendingGUIUpdateEvents()
+{
+ gruel::scoped_lock lock(d_mutex);
+ unsigned int returnValue = 0;
+ returnValue = _pendingGUIUpdateEventsCount;
+ return returnValue;
+}
+
+void
+SpectrumGUIClass::IncrementPendingGUIUpdateEvents()
+{
+ gruel::scoped_lock lock(d_mutex);
+ _pendingGUIUpdateEventsCount++;
+}
+
+void
+SpectrumGUIClass::DecrementPendingGUIUpdateEvents()
+{
+ gruel::scoped_lock lock(d_mutex);
+ if(_pendingGUIUpdateEventsCount > 0){
+ _pendingGUIUpdateEventsCount--;
+ }
+}
+
+void
+SpectrumGUIClass::ResetPendingGUIUpdateEvents()
+{
+ gruel::scoped_lock lock(d_mutex);
+ _pendingGUIUpdateEventsCount = 0;
+}
+
+
+QWidget*
+SpectrumGUIClass::qwidget()
+{
+ gruel::scoped_lock lock(d_mutex);
+ return (QWidget*)_spectrumDisplayForm;
+}
+
+void
+SpectrumGUIClass::SetTimeDomainAxis(double min, double max)
+{
+ gruel::scoped_lock lock(d_mutex);
+ _spectrumDisplayForm->SetTimeDomainAxis(min, max);
+}
+
+void
+SpectrumGUIClass::SetConstellationAxis(double xmin, double xmax,
+ double ymin, double ymax)
+{
+ gruel::scoped_lock lock(d_mutex);
+ _spectrumDisplayForm->SetConstellationAxis(xmin, xmax, ymin, ymax);
+}
+
+void
+SpectrumGUIClass::SetConstellationPenSize(int size)
+{
+ gruel::scoped_lock lock(d_mutex);
+ _spectrumDisplayForm->SetConstellationPenSize(size);
+}
+
+
+void
+SpectrumGUIClass::SetFrequencyAxis(double min, double max)
+{
+ gruel::scoped_lock lock(d_mutex);
+ _spectrumDisplayForm->SetFrequencyAxis(min, max);
+}
+
+void
+SpectrumGUIClass::SetUpdateTime(double t)
+{
+ gruel::scoped_lock lock(d_mutex);
+ _updateTime = t;
+ _spectrumDisplayForm->SetUpdateTime(_updateTime);
+}
+
+
+#endif /* SPECTRUM_GUI_CLASS_CPP */