diff options
Diffstat (limited to 'gr-qtgui/src/lib')
26 files changed, 570 insertions, 1390 deletions
diff --git a/gr-qtgui/src/lib/.gitignore b/gr-qtgui/src/lib/.gitignore index 58c8081e5..11bb4342a 100644 --- a/gr-qtgui/src/lib/.gitignore +++ b/gr-qtgui/src/lib/.gitignore @@ -4,10 +4,10 @@ /.deps /qtgui.cc /qtgui.py -/WaterfallDisplayPlot_moc.cc -/Waterfall3DDisplayPlot_moc.cc -/TimeDomainDisplayPlot_moc.cc -/spectrumdisplayform_moc.cc -/spectrumdisplayform_ui.h -/FrequencyDisplayPlot_moc.cc -/ConstellationDisplayPlot_moc.cc +/WaterfallDisplayPlot.moc.cc +/Waterfall3DDisplayPlot.moc.cc +/TimeDomainDisplayPlot.moc.cc +/spectrumdisplayform.moc.cc +/spectrumdisplayform.ui.h +/FrequencyDisplayPlot.moc.cc +/ConstellationDisplayPlot.moc.cc diff --git a/gr-qtgui/src/lib/ConstellationDisplayPlot.cc b/gr-qtgui/src/lib/ConstellationDisplayPlot.cc index 80bf4503f..9ad5bdd3c 100644 --- a/gr-qtgui/src/lib/ConstellationDisplayPlot.cc +++ b/gr-qtgui/src/lib/ConstellationDisplayPlot.cc @@ -24,10 +24,11 @@ public: } protected: + using QwtPlotZoomer::trackerText; virtual QwtText trackerText( const QwtDoublePoint& p ) const { - QwtText t(QString("Sample %1, %2 V").arg(p.x(), 0, 'f', 0).arg(p.y(), 0, 'f', 4)); - + QwtText t(QString("(%1, %2)").arg(p.x(), 0, 'f', 4). + arg(p.y(), 0, 'f', 4)); return t; } }; @@ -39,8 +40,6 @@ ConstellationDisplayPlot::ConstellationDisplayPlot(QWidget* parent) resize(parent->width(), parent->height()); - _displayIntervalTime = (1.0/10.0); // 1/10 of a second between updates - _numPoints = 1024; _penSize = 5; _realDataPoints = new double[_numPoints]; @@ -58,12 +57,10 @@ ConstellationDisplayPlot::ConstellationDisplayPlot(QWidget* parent) canvas()->setPalette(palette); setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine); - //setAxisScale(QwtPlot::xBottom, -1.0, 1.0); set_xaxis(-2.0, 2.0); setAxisTitle(QwtPlot::xBottom, "In-phase"); setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine); - //setAxisScale(QwtPlot::yLeft, -1.0, 1.0); set_yaxis(-2.0, 2.0); setAxisTitle(QwtPlot::yLeft, "Quadrature"); @@ -148,19 +145,9 @@ ConstellationDisplayPlot::set_axis(double xmin, double xmax, set_yaxis(ymin, ymax); } -void ConstellationDisplayPlot::replot(){ - - const timespec startTime = get_highres_clock(); - +void ConstellationDisplayPlot::replot() +{ QwtPlot::replot(); - - double differenceTime = (diff_timespec(get_highres_clock(), startTime)); - - differenceTime *= 99.0; - // Require at least a 10% duty cycle - if(differenceTime > (1.0/10.0)){ - _displayIntervalTime = differenceTime; - } } void @@ -171,10 +158,12 @@ ConstellationDisplayPlot::resizeSlot( QSize *s ) void ConstellationDisplayPlot::PlotNewData(const double* realDataPoints, const double* imagDataPoints, - const int64_t numDataPoints) + const int64_t numDataPoints, + const double timeInterval) { - if(numDataPoints > 0){ - + if((numDataPoints > 0) && + (diff_timespec(get_highres_clock(), _lastReplot) > timeInterval)) { + if(numDataPoints != _numPoints){ _numPoints = numDataPoints; @@ -185,17 +174,12 @@ void ConstellationDisplayPlot::PlotNewData(const double* realDataPoints, _plot_curve->setRawData(_realDataPoints, _imagDataPoints, _numPoints); } + memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double)); memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double)); - } - - // Allow at least a 50% duty cycle - if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){ - // Only replot the screen if it is visible - if(isVisible()){ - replot(); - } + replot(); + _lastReplot = get_highres_clock(); } } diff --git a/gr-qtgui/src/lib/ConstellationDisplayPlot.h b/gr-qtgui/src/lib/ConstellationDisplayPlot.h index 99ae566e0..a441a8bfe 100644 --- a/gr-qtgui/src/lib/ConstellationDisplayPlot.h +++ b/gr-qtgui/src/lib/ConstellationDisplayPlot.h @@ -24,7 +24,8 @@ public: void PlotNewData(const double* realDataPoints, const double* imagDataPoints, - const int64_t numDataPoints); + const int64_t numDataPoints, + const double timeInterval); virtual void replot(); @@ -55,8 +56,6 @@ private: int64_t _numPoints; int64_t _penSize; - - double _displayIntervalTime; }; #endif /* CONSTELLATION_DISPLAY_PLOT_HPP */ diff --git a/gr-qtgui/src/lib/FrequencyDisplayPlot.cc b/gr-qtgui/src/lib/FrequencyDisplayPlot.cc index 7deff8543..d150e2e4c 100644 --- a/gr-qtgui/src/lib/FrequencyDisplayPlot.cc +++ b/gr-qtgui/src/lib/FrequencyDisplayPlot.cc @@ -73,15 +73,23 @@ public: updateDisplay(); } -protected: - virtual QwtText trackerText( const QwtDoublePoint& p ) const + void SetUnitType(const std::string &type) { - QString strunits = (GetFrequencyPrecision() == 0) ? "Hz" : "kHz"; - QwtText t(QString("%1 %2, %3 dB").arg(p.x(), 0, 'f', - GetFrequencyPrecision()).arg(strunits).arg(p.y(), 0, 'f', 2)); + _unitType = type; + } +protected: + using QwtPlotZoomer::trackerText; + virtual QwtText trackerText( const QwtDoublePoint& p ) const + { + QwtText t(QString("%1 %2, %3 dB"). + arg(p.x(), 0, 'f', GetFrequencyPrecision()). + arg(_unitType.c_str()).arg(p.y(), 0, 'f', 2)); return t; } + +private: + std::string _unitType; }; FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent) @@ -94,8 +102,6 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent) resize(parent->width(), parent->height()); - _displayIntervalTime = (1.0/10.0); // 1/10 of a second between updates - _useCenterFrequencyFlag = false; _numPoints = 1024; @@ -115,9 +121,8 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent) palette.setColor(canvas()->backgroundRole(), QColor("white")); canvas()->setPalette(palette); - setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(0)); - setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency); setAxisTitle(QwtPlot::xBottom, "Frequency (Hz)"); + setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(0)); _minYAxis = -120; _maxYAxis = 10; @@ -150,7 +155,7 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent) _upper_intensity_marker = new QwtPlotMarker(); _upper_intensity_marker->setLineStyle(QwtPlotMarker::HLine); - _upper_intensity_marker->setLinePen(QPen(Qt::green)); + _upper_intensity_marker->setLinePen(QPen(Qt::green, 0, Qt::DotLine)); _upper_intensity_marker->attach(this); memset(_dataPoints, 0x0, _numPoints*sizeof(double)); @@ -161,9 +166,6 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent) _maxFFTPoints[number] = -280.0; } - _resetXAxisPoints(); - - // set up peak marker QwtSymbol symbol; @@ -213,6 +215,9 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent) const QColor c(Qt::darkRed); _zoomer->setRubberBandPen(c); _zoomer->setTrackerPen(c); + + // Do this after the zoomer has been built + _resetXAxisPoints(); } FrequencyDisplayPlot::~FrequencyDisplayPlot() @@ -258,21 +263,26 @@ FrequencyDisplayPlot::SetFrequencyRange(const double constStartFreq, stopFreq = (stopFreq + centerFreq); } - _startFrequency = startFreq; - _stopFrequency = stopFreq; - _resetXAxisPoints(); - - double display_units = ceil(log10(units)/2.0); - setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency); - setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(display_units)); - setAxisTitle(QwtPlot::xBottom, QString("Frequency (%1)").arg(strunits.c_str())); - ((FreqDisplayZoomer*)_zoomer)->SetFrequencyPrecision(display_units); - - // Load up the new base zoom settings - _zoomer->setZoomBase(); - - // Zooms back to the base and clears any other zoom levels - _zoomer->zoom(0); + bool reset = false; + if((startFreq != _startFrequency) || (stopFreq != _stopFrequency)) + reset = true; + + if(stopFreq > startFreq) { + _startFrequency = startFreq; + _stopFrequency = stopFreq; + + if((axisScaleDraw(QwtPlot::xBottom) != NULL) && (_zoomer != NULL)){ + double display_units = ceil(log10(units)/2.0); + setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(display_units)); + setAxisTitle(QwtPlot::xBottom, QString("Frequency (%1)").arg(strunits.c_str())); + + if(reset) + _resetXAxisPoints(); + + ((FreqDisplayZoomer*)_zoomer)->SetFrequencyPrecision(display_units); + ((FreqDisplayZoomer*)_zoomer)->SetUnitType(strunits); + } + } } @@ -291,8 +301,6 @@ FrequencyDisplayPlot::GetStopFrequency() const void FrequencyDisplayPlot::replot() { - const timespec startTime = get_highres_clock(); - _markerNoiseFloorAmplitude->setYValue(_noiseFloorAmplitude); // Make sure to take into account the start frequency @@ -305,14 +313,6 @@ FrequencyDisplayPlot::replot() _markerPeakAmplitude->setYValue(_peakAmplitude); QwtPlot::replot(); - - double differenceTime = (diff_timespec(get_highres_clock(), startTime)); - - differenceTime *= 99.0; - // Require at least a 10% duty cycle - if(differenceTime > (1.0/10.0)){ - _displayIntervalTime = differenceTime; - } } void @@ -324,13 +324,15 @@ FrequencyDisplayPlot::resizeSlot( QSize *s ) void FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDataPoints, const double noiseFloorAmplitude, const double peakFrequency, - const double peakAmplitude) + const double peakAmplitude, const double timeInterval) { - if(numDataPoints > 0){ - - if(numDataPoints != _numPoints){ + // Only update plot if there is data and if the time interval has elapsed + if((numDataPoints > 0) && + (diff_timespec(get_highres_clock(), _lastReplot) > timeInterval)) { + + if(numDataPoints != _numPoints) { _numPoints = numDataPoints; - + delete[] _dataPoints; delete[] _minFFTPoints; delete[] _maxFFTPoints; @@ -343,12 +345,12 @@ FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDat _fft_plot_curve->setRawData(_xAxisPoints, _dataPoints, _numPoints); _min_fft_plot_curve->setRawData(_xAxisPoints, _minFFTPoints, _numPoints); _max_fft_plot_curve->setRawData(_xAxisPoints, _maxFFTPoints, _numPoints); - + _resetXAxisPoints(); ClearMaxData(); ClearMinData(); } - + memcpy(_dataPoints, dataPoints, numDataPoints*sizeof(double)); for(int64_t point = 0; point < numDataPoints; point++){ if(dataPoints[point] < _minFFTPoints[point]){ @@ -363,14 +365,10 @@ FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDat _peakFrequency = peakFrequency; _peakAmplitude = peakAmplitude; - } + SetUpperIntensityLevel(_peakAmplitude); - // Allow at least a 50% duty cycle - if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){ - // Only replot the screen if it is visible - if(isVisible()){ - replot(); - } + replot(); + _lastReplot = get_highres_clock(); } } @@ -412,6 +410,17 @@ FrequencyDisplayPlot::_resetXAxisPoints() _xAxisPoints[loc] = freqValue; freqValue += fft_bin_size; } + + setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency); + + // Set up zoomer base for maximum unzoom x-axis + // and reset to maximum unzoom level + QwtDoubleRect zbase = _zoomer->zoomBase(); + zbase.setLeft(_startFrequency); + zbase.setRight(_stopFrequency); + _zoomer->zoom(zbase); + _zoomer->setZoomBase(zbase); + _zoomer->zoom(0); } void diff --git a/gr-qtgui/src/lib/FrequencyDisplayPlot.h b/gr-qtgui/src/lib/FrequencyDisplayPlot.h index 785efe694..c78e1667e 100644 --- a/gr-qtgui/src/lib/FrequencyDisplayPlot.h +++ b/gr-qtgui/src/lib/FrequencyDisplayPlot.h @@ -30,7 +30,7 @@ public: void PlotNewData(const double* dataPoints, const int64_t numDataPoints, const double noiseFloorAmplitude, const double peakFrequency, - const double peakAmplitude); + const double peakAmplitude, const double timeInterval); void ClearMaxData(); void ClearMinData(); @@ -86,8 +86,6 @@ private: timespec _lastReplot; bool _useCenterFrequencyFlag; - - double _displayIntervalTime; }; #endif /* FREQUENCY_DISPLAY_PLOT_HPP */ diff --git a/gr-qtgui/src/lib/Makefile.am b/gr-qtgui/src/lib/Makefile.am index 814bee136..4ba637ad6 100644 --- a/gr-qtgui/src/lib/Makefile.am +++ b/gr-qtgui/src/lib/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2008,2009 Free Software Foundation, Inc. +# Copyright 2008,2009,2010 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -27,13 +27,12 @@ AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) \ # Only include these files in the build if qtgui passes configure checks # This is mostly to help make distcheck pass QMAKE_SOURCES = \ - spectrumdisplayform_moc.cc \ - FrequencyDisplayPlot_moc.cc \ - TimeDomainDisplayPlot_moc.cc \ - WaterfallDisplayPlot_moc.cc \ - Waterfall3DDisplayPlot_moc.cc \ - ConstellationDisplayPlot_moc.cc \ - spectrumdisplayform_ui.h + spectrumdisplayform.moc.cc \ + FrequencyDisplayPlot.moc.cc \ + TimeDomainDisplayPlot.moc.cc \ + WaterfallDisplayPlot.moc.cc \ + ConstellationDisplayPlot.moc.cc \ + spectrumdisplayform.ui.h EXTRA_DIST = spectrumdisplayform.ui @@ -47,23 +46,22 @@ libgnuradio_qtgui_la_SOURCES = \ FrequencyDisplayPlot.cc \ TimeDomainDisplayPlot.cc \ WaterfallDisplayPlot.cc \ - Waterfall3DDisplayPlot.cc \ waterfallGlobalData.cc \ ConstellationDisplayPlot.cc \ spectrumdisplayform.cc \ SpectrumGUIClass.cc \ spectrumUpdateEvents.cc \ plot_waterfall.cc \ - $(QMAKE_SOURCES) \ qtgui_sink_c.cc \ qtgui_sink_f.cc +nodist_libgnuradio_qtgui_la_SOURCES=$(BUILT_SOURCES) + # These headers get installed in ${prefix}/include/gnuradio grinclude_HEADERS = \ FrequencyDisplayPlot.h \ TimeDomainDisplayPlot.h \ WaterfallDisplayPlot.h \ - Waterfall3DDisplayPlot.h \ waterfallGlobalData.h \ ConstellationDisplayPlot.h \ highResTimeFunctions.h \ @@ -75,14 +73,15 @@ grinclude_HEADERS = \ qtgui_sink_c.h \ qtgui_sink_f.h -%_moc.cc : %.h - $(QT_MOC_EXEC) -DQT_SHARED -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -p $(srcdir) $< -o $@ +QT_MOC_FLAGS=-DQT_SHARED -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB +%.moc.cc : %.h + $(QT_MOC_EXEC) $(QT_MOC_FLAGS) -p $(srcdir) $< -o $@ -%_ui.h : %.ui +%.ui.h : %.ui $(QT_UIC_EXEC) $< -o $@ # magic flags -libgnuradio_qtgui_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 +libgnuradio_qtgui_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS) libgnuradio_qtgui_la_LIBADD = \ $(GNURADIO_CORE_LA) \ diff --git a/gr-qtgui/src/lib/SpectrumGUIClass.cc b/gr-qtgui/src/lib/SpectrumGUIClass.cc index 4cb71a31a..563ed34ba 100644 --- a/gr-qtgui/src/lib/SpectrumGUIClass.cc +++ b/gr-qtgui/src/lib/SpectrumGUIClass.cc @@ -61,8 +61,7 @@ SpectrumGUIClass::~SpectrumGUIClass() void SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent, const bool frequency, const bool waterfall, - const bool waterfall3d, const bool time, - const bool constellation, + const bool time, const bool constellation, const bool use_openGL) { //_windowStateLock->Lock(); @@ -87,7 +86,6 @@ SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent, // Toggle Windows on/off _spectrumDisplayForm->ToggleTabFrequency(frequency); _spectrumDisplayForm->ToggleTabWaterfall(waterfall); - _spectrumDisplayForm->ToggleTabWaterfall3D(waterfall3d); _spectrumDisplayForm->ToggleTabTime(time); _spectrumDisplayForm->ToggleTabConstellation(constellation); @@ -111,7 +109,7 @@ SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent, timespec_reset(&_lastGUIUpdateTime); // Draw Blank Display - UpdateWindow(false, NULL, 0, NULL, 0, NULL, 0, 1.0, get_highres_clock(), true); + UpdateWindow(false, NULL, 0, NULL, 0, NULL, 0, get_highres_clock(), true); // Set up the initial frequency axis settings SetFrequencyRange(_centerFrequency, _startFrequency, _stopFrequency); @@ -220,7 +218,6 @@ SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag, const uint64_t realTimeDomainDataSize, const float* complexTimeDomainData, const uint64_t complexTimeDomainDataSize, - const double timePerFFT, const timespec timestamp, const bool lastOfMultipleFFTUpdateFlag) { @@ -277,7 +274,7 @@ SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag, const timespec currentTime = get_highres_clock(); const timespec lastUpdateGUITime = GetLastGUIUpdateTime(); - if((diff_timespec(currentTime, lastUpdateGUITime) > (4*timePerFFT)) && + if((diff_timespec(currentTime, lastUpdateGUITime) > (4*_updateTime)) && (GetPendingGUIUpdateEvents() > 0) && !timespec_empty(&lastUpdateGUITime)) { // Do not update the display if too much data is pending to be displayed _droppedEntriesCount++; @@ -290,7 +287,7 @@ SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag, _realTimeDomainPoints, _imagTimeDomainPoints, timeDomainBufferSize, - timePerFFT, timestamp, + timestamp, repeatDataFlag, lastOfMultipleFFTUpdateFlag, currentTime, @@ -460,4 +457,12 @@ SpectrumGUIClass::SetFrequencyAxis(double min, double max) _spectrumDisplayForm->SetFrequencyAxis(min, max); } +void +SpectrumGUIClass::SetUpdateTime(double t) +{ + _updateTime = t; + _spectrumDisplayForm->SetUpdateTime(_updateTime); +} + + #endif /* SPECTRUM_GUI_CLASS_CPP */ diff --git a/gr-qtgui/src/lib/SpectrumGUIClass.h b/gr-qtgui/src/lib/SpectrumGUIClass.h index d8dcb2769..63a340c34 100644 --- a/gr-qtgui/src/lib/SpectrumGUIClass.h +++ b/gr-qtgui/src/lib/SpectrumGUIClass.h @@ -31,8 +31,7 @@ public: void OpenSpectrumWindow(QWidget*, const bool frequency=true, const bool waterfall=true, - const bool waterfall3d=true, const bool time=true, - const bool constellation=true, + const bool time=true, const bool constellation=true, const bool use_openGL=true); void SetDisplayTitle(const std::string); @@ -47,7 +46,7 @@ public: void UpdateWindow(const bool, const std::complex<float>*, const uint64_t, const float*, const uint64_t, const float*, - const uint64_t, const double, + const uint64_t, const timespec, const bool); float GetPowerValue()const; @@ -79,6 +78,8 @@ public: void SetConstellationPenSize(int size); void SetFrequencyAxis(double min, double max); + void SetUpdateTime(double t); + protected: private: @@ -98,6 +99,7 @@ private: unsigned int _pendingGUIUpdateEventsCount; int _droppedEntriesCount; bool _fftBuffersCreatedFlag; + double _updateTime; SpectrumDisplayForm* _spectrumDisplayForm; diff --git a/gr-qtgui/src/lib/TimeDomainDisplayPlot.cc b/gr-qtgui/src/lib/TimeDomainDisplayPlot.cc index cb18b4418..9c98cec5b 100644 --- a/gr-qtgui/src/lib/TimeDomainDisplayPlot.cc +++ b/gr-qtgui/src/lib/TimeDomainDisplayPlot.cc @@ -7,10 +7,37 @@ #include <qwt_legend.h> -class TimeDomainDisplayZoomer: public QwtPlotZoomer +class TimePrecisionClass { public: - TimeDomainDisplayZoomer(QwtPlotCanvas* canvas):QwtPlotZoomer(canvas) + TimePrecisionClass(const int timePrecision) + { + _timePrecision = timePrecision; + } + + virtual ~TimePrecisionClass() + { + } + + virtual unsigned int GetTimePrecision() const + { + return _timePrecision; + } + + virtual void SetTimePrecision(const unsigned int newPrecision) + { + _timePrecision = newPrecision; + } +protected: + unsigned int _timePrecision; +}; + + +class TimeDomainDisplayZoomer: public QwtPlotZoomer, public TimePrecisionClass +{ +public: + TimeDomainDisplayZoomer(QwtPlotCanvas* canvas, const unsigned int timePrecision) + : QwtPlotZoomer(canvas),TimePrecisionClass(timePrecision) { setTrackerMode(QwtPicker::AlwaysOn); } @@ -23,28 +50,38 @@ public: updateDisplay(); } + void SetUnitType(const std::string &type) + { + _unitType = type; + } + protected: + using QwtPlotZoomer::trackerText; virtual QwtText trackerText( const QwtDoublePoint& p ) const { - QwtText t(QString("Sample %1, %2 V").arg(p.x(), 0, 'f', 0).arg(p.y(), 0, 'f', 4)); + QwtText t(QString("%1 %2, %3 V").arg(p.x(), 0, 'f', GetTimePrecision()). + arg(_unitType.c_str()). + arg(p.y(), 0, 'f', 4)); return t; } + +private: + std::string _unitType; }; -TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent){ +TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent) +{ timespec_reset(&_lastReplot); resize(parent->width(), parent->height()); - _displayIntervalTime = (1.0/10.0); // 1/10 of a second between updates - _numPoints = 1024; _realDataPoints = new double[_numPoints]; _imagDataPoints = new double[_numPoints]; _xAxisPoints = new double[_numPoints]; - _zoomer = new TimeDomainDisplayZoomer(canvas()); + _zoomer = new TimeDomainDisplayZoomer(canvas(), 0); // Disable polygon clipping QwtPainter::setDeviceClipping(false); @@ -59,7 +96,7 @@ TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent){ setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine); set_xaxis(0, _numPoints); - setAxisTitle(QwtPlot::xBottom, "Sample Number"); + setAxisTitle(QwtPlot::xBottom, "Time (sec)"); setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine); set_yaxis(-2.0, 2.0); @@ -81,6 +118,7 @@ TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent){ memset(_imagDataPoints, 0x0, _numPoints*sizeof(double)); memset(_xAxisPoints, 0x0, _numPoints*sizeof(double)); + _sampleRate = 1; _resetXAxisPoints(); replot(); @@ -114,7 +152,8 @@ TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent){ 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 ) )); } TimeDomainDisplayPlot::~TimeDomainDisplayPlot(){ @@ -143,17 +182,7 @@ TimeDomainDisplayPlot::set_xaxis(double min, double max) void TimeDomainDisplayPlot::replot() { - const timespec startTime = get_highres_clock(); - QwtPlot::replot(); - - double differenceTime = (diff_timespec(get_highres_clock(), startTime)); - - differenceTime *= 99.0; - // Require at least a 10% duty cycle - if(differenceTime > (1.0/10.0)){ - _displayIntervalTime = differenceTime; - } } void @@ -164,10 +193,12 @@ TimeDomainDisplayPlot::resizeSlot( QSize *s ) void TimeDomainDisplayPlot::PlotNewData(const double* realDataPoints, const double* imagDataPoints, - const int64_t numDataPoints) + const int64_t numDataPoints, + const double timeInterval) { - if(numDataPoints > 0){ - + if((numDataPoints > 0) && + (diff_timespec(get_highres_clock(), _lastReplot) > timeInterval)) { + if(numDataPoints != _numPoints){ _numPoints = numDataPoints; @@ -185,34 +216,61 @@ void TimeDomainDisplayPlot::PlotNewData(const double* realDataPoints, _resetXAxisPoints(); } + memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double)); memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double)); - } + replot(); - // Allow at least a 50% duty cycle - if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){ - // Only replot the screen if it is visible - if(isVisible()){ - replot(); - } _lastReplot = get_highres_clock(); } } -void TimeDomainDisplayPlot::SetImaginaryDataVisible(const bool visibleFlag){ +void TimeDomainDisplayPlot::SetImaginaryDataVisible(const bool visibleFlag) +{ _imag_plot_curve->setVisible(visibleFlag); } -void TimeDomainDisplayPlot::_resetXAxisPoints(){ +void TimeDomainDisplayPlot::_resetXAxisPoints() +{ + double delt = 1.0/_sampleRate; for(long loc = 0; loc < _numPoints; loc++){ - _xAxisPoints[loc] = loc; + _xAxisPoints[loc] = loc*delt; } - setAxisScale(QwtPlot::xBottom, 0, _numPoints); + setAxisScale(QwtPlot::xBottom, 0, _numPoints*delt); + + // Set up zoomer base for maximum unzoom x-axis + // and reset to maximum unzoom level + QwtDoubleRect zbase = _zoomer->zoomBase(); + zbase.setLeft(0); + zbase.setRight(_numPoints*delt); + _zoomer->zoom(zbase); + _zoomer->setZoomBase(zbase); + _zoomer->zoom(0); } -void TimeDomainDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on){ +void TimeDomainDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on) +{ plotItem->setVisible(!on); } +void +TimeDomainDisplayPlot::SetSampleRate(double sr, double units, + const std::string &strunits) +{ + double newsr = sr/units; + if(newsr != _sampleRate) { + _sampleRate = sr/units; + _resetXAxisPoints(); + + // While we could change the displayed sigfigs based on the unit being + // displayed, I think it looks better by just setting it to 4 regardless. + //double display_units = ceil(log10(units)/2.0); + double display_units = 4; + setAxisTitle(QwtPlot::xBottom, QString("Time (%1)").arg(strunits.c_str())); + ((TimeDomainDisplayZoomer*)_zoomer)->SetTimePrecision(display_units); + ((TimeDomainDisplayZoomer*)_zoomer)->SetUnitType(strunits); + } +} + #endif /* TIME_DOMAIN_DISPLAY_PLOT_C */ diff --git a/gr-qtgui/src/lib/TimeDomainDisplayPlot.h b/gr-qtgui/src/lib/TimeDomainDisplayPlot.h index 8d98abac6..5525bbabe 100644 --- a/gr-qtgui/src/lib/TimeDomainDisplayPlot.h +++ b/gr-qtgui/src/lib/TimeDomainDisplayPlot.h @@ -21,7 +21,8 @@ public: TimeDomainDisplayPlot(QWidget*); virtual ~TimeDomainDisplayPlot(); - void PlotNewData(const double* realDataPoints, const double* imagDataPoints, const int64_t numDataPoints); + void PlotNewData(const double* realDataPoints, const double* imagDataPoints, + const int64_t numDataPoints, const double timeInterval); void SetImaginaryDataVisible(const bool); @@ -32,6 +33,8 @@ public: public slots: void resizeSlot( QSize *s ); + void SetSampleRate(double sr, double units, + const std::string &strunits); protected slots: void LegendEntryChecked(QwtPlotItem *plotItem, bool on); @@ -51,11 +54,11 @@ private: double* _imagDataPoints; double* _xAxisPoints; + double _sampleRate; + timespec _lastReplot; int64_t _numPoints; - - double _displayIntervalTime; }; #endif /* TIME_DOMAIN_DISPLAY_PLOT_HPP */ diff --git a/gr-qtgui/src/lib/Waterfall3DDisplayPlot.cc b/gr-qtgui/src/lib/Waterfall3DDisplayPlot.cc deleted file mode 100644 index f676cb4af..000000000 --- a/gr-qtgui/src/lib/Waterfall3DDisplayPlot.cc +++ /dev/null @@ -1,410 +0,0 @@ -#ifndef WATERFALL_3D_DISPLAY_PLOT_C -#define WATERFALL_3D_DISPLAY_PLOT_C - -#include <Waterfall3DDisplayPlot.h> - -#include <qwt3d_helper.h> -#include <qapplication.h> - -Waterfall3DColorMap::Waterfall3DColorMap(): Qwt3D::Color(), QwtLinearColorMap(){ - _interval.setInterval(0, 1.0); - -} - -Waterfall3DColorMap::~Waterfall3DColorMap(){ - -} - -Qwt3D::RGBA -Waterfall3DColorMap::operator()(double, double, double z) const -{ - return Qwt3D::RGBA(Qwt3D::Qt2GL(color(_interval, z))); -} - -void -Waterfall3DColorMap::SetInterval(const double minValue, const double maxValue) -{ - _interval.setInterval(minValue, maxValue); -} - -Qwt3D::ColorVector& -Waterfall3DColorMap::createVector(Qwt3D::ColorVector& vec) -{ - // Generate 100 interval values and then return those - Qwt3D::ColorVector colorVec; - for(unsigned int number = 0; number < 100; number++){ - double value = (_interval.width() * (static_cast<double>(number) / 100.0)) + _interval.minValue(); - colorVec.push_back(operator()(0,0,value)); - } - vec = colorVec; - return vec; -} - - -const int Waterfall3DDisplayPlot::INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR; -const int Waterfall3DDisplayPlot::INTENSITY_COLOR_MAP_TYPE_WHITE_HOT; -const int Waterfall3DDisplayPlot::INTENSITY_COLOR_MAP_TYPE_BLACK_HOT; -const int Waterfall3DDisplayPlot::INTENSITY_COLOR_MAP_TYPE_INCANDESCENT; -const int Waterfall3DDisplayPlot::INTENSITY_COLOR_MAP_TYPE_USER_DEFINED; - -Waterfall3DDisplayPlot::Waterfall3DDisplayPlot(QWidget* parent):Qwt3D::SurfacePlot(parent) -{ - _startFrequency = 0; - _stopFrequency = 4000; - - _createCoordinateSystemFlag = true; - - _initialized = false; - - _numPoints = 1024; - - _displayIntervalTime = (1.0/5.0); // 1/5 of a second between updates - - timespec_reset(&_lastReplot); - - _useCenterFrequencyFlag = false; - _centerFrequency = 0.0; - - _timePerFFT = 1.0; - timespec_reset(&_dataTimestamp); - - coordinates()->setAutoScale(false); - - _waterfallData = new Waterfall3DData(_startFrequency, _stopFrequency, _numPoints, 200); - _waterfallData->assign(this); - _waterfallData->create(); - - _intensityColorMapType = -1; - SetIntensityColorMapType(INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR, Qt::white, Qt::black, true, true); - - legend()->setScale(Qwt3D::LINEARSCALE); - legend()->setTitleString("Intensity"); - - enableMouse(true); -} - -Waterfall3DDisplayPlot::~Waterfall3DDisplayPlot() -{ - delete _waterfallData; -} - -void -Waterfall3DDisplayPlot::Init() -{ - if(!_initialized && initializedGL()){ - resize(parentWidget()->width(), parentWidget()->height()); - - // Attempting to prevent valgrind uninitialized variable errors in QwtPlot3d::Drawable class - glDisable(GL_POLYGON_OFFSET_FILL); - - setPlotStyle(Qwt3D::FILLED); - - setCoordinateStyle(Qwt3D::FRAME); - setFloorStyle(Qwt3D::FLOORDATA); - setOrtho(true); - - _initialized = true; - } -} - -void -Waterfall3DDisplayPlot::Reset() -{ - _waterfallData->ResizeData(_startFrequency, _stopFrequency, _numPoints); - _waterfallData->Reset(); - - if(initializedGL()){ - setScale(1, static_cast<int>(((_stopFrequency - _startFrequency) / 200) ), 10); - } - - _createCoordinateSystemFlag = true; - - timespec_reset(&_dataTimestamp); - _timePerFFT = 1.0; -} - -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; - - _useCenterFrequencyFlag = useCenterFrequencyFlag; - _centerFrequency = centerFreq; - - Reset(); - - // Only replot if screen is visible - if(isVisible()){ - replot(); - } - } -} - -bool -Waterfall3DDisplayPlot::loadFromData(double** data, unsigned int columns, unsigned int rows - ,double minx, double maxx, double miny, double maxy) -{ - - Qwt3D::GridData* gridPtr = (Qwt3D::GridData*)actualData_p; - - gridPtr->setPeriodic(false,false); - gridPtr->setSize(columns,rows); - readIn(*gridPtr,data,columns,rows,minx,maxx,miny,maxy); - calcNormals(*gridPtr); - - updateData(); - updateNormals(); - - if( _createCoordinateSystemFlag ){ - createCoordinateSystem(); - - for (unsigned i=0; i!=coordinates()->axes.size(); ++i) - { - coordinates()->axes[i].setMajors(5); - coordinates()->axes[i].setMinors(3); - } - - coordinates()->axes[Qwt3D::Y1].setLabelString("Time"); - coordinates()->axes[Qwt3D::Y2].setLabelString("Time"); - coordinates()->axes[Qwt3D::Y3].setLabelString("Time"); - coordinates()->axes[Qwt3D::Y4].setLabelString("Time"); - coordinates()->axes[Qwt3D::Z1].setLabelString("Intensity (dB)"); - coordinates()->axes[Qwt3D::Z2].setLabelString("Intensity (dB)"); - coordinates()->axes[Qwt3D::Z3].setLabelString("Intensity (dB)"); - coordinates()->axes[Qwt3D::Z4].setLabelString("Intensity (dB)"); - - coordinates()->axes[Qwt3D::X1].setLabelString((!_useCenterFrequencyFlag ? "Frequency (Hz)" : "Frequency (kHz)")); - coordinates()->axes[Qwt3D::X2].setLabelString((!_useCenterFrequencyFlag ? "Frequency (Hz)" : "Frequency (kHz)")); - coordinates()->axes[Qwt3D::X3].setLabelString((!_useCenterFrequencyFlag ? "Frequency (Hz)" : "Frequency (kHz)")); - coordinates()->axes[Qwt3D::X4].setLabelString((!_useCenterFrequencyFlag ? "Frequency (Hz)" : "Frequency (kHz)")); - - // The QwtPlot3D Interface takes ownership of these items, so there is no need to delete them... - coordinates()->axes[Qwt3D::X1].setScale(new FrequencyScale(_useCenterFrequencyFlag, _centerFrequency)); - coordinates()->axes[Qwt3D::X2].setScale(new FrequencyScale(_useCenterFrequencyFlag, _centerFrequency)); - coordinates()->axes[Qwt3D::X3].setScale(new FrequencyScale(_useCenterFrequencyFlag, _centerFrequency)); - coordinates()->axes[Qwt3D::X4].setScale(new FrequencyScale(_useCenterFrequencyFlag, _centerFrequency)); - - coordinates()->axes[Qwt3D::Y1].setScale(new TimeScale(this)); - coordinates()->axes[Qwt3D::Y2].setScale(new TimeScale(this)); - coordinates()->axes[Qwt3D::Y3].setScale(new TimeScale(this)); - coordinates()->axes[Qwt3D::Y4].setScale(new TimeScale(this)); - - coordinates()->axes[Qwt3D::Z1].setScale(new IntensityScale(_waterfallData->GetFloorValue())); - coordinates()->axes[Qwt3D::Z2].setScale(new IntensityScale(_waterfallData->GetFloorValue())); - coordinates()->axes[Qwt3D::Z3].setScale(new IntensityScale(_waterfallData->GetFloorValue())); - coordinates()->axes[Qwt3D::Z4].setScale(new IntensityScale(_waterfallData->GetFloorValue())); - - _createCoordinateSystemFlag = false; - } - - return true; -} - -double -Waterfall3DDisplayPlot::GetStartFrequency() const -{ - return _startFrequency; -} - -double -Waterfall3DDisplayPlot::GetStopFrequency() const -{ - return _stopFrequency; -} - -void -Waterfall3DDisplayPlot::PlotNewData(const double* dataPoints, - const int64_t numDataPoints, - const double timePerFFT, - const timespec timestamp, - const int droppedFrames) -{ - if(numDataPoints > 0){ - if(numDataPoints != _numPoints){ - _numPoints = numDataPoints; - - Reset(); - - if(isVisible()){ - replot(); - } - - _createCoordinateSystemFlag = true; - - _lastReplot = get_highres_clock(); - } - - _dataTimestamp = timestamp; - _timePerFFT = timePerFFT; - - _waterfallData->addFFTData(dataPoints, numDataPoints, droppedFrames); - _waterfallData->IncrementNumLinesToUpdate(); - } - - // Allow at least a 50% duty cycle - if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){ - // Only update when window is visible - if(isVisible()){ - replot(); - } - - _lastReplot = get_highres_clock(); - } -} - -void -Waterfall3DDisplayPlot::SetIntensityRange(const double minIntensity, - const double maxIntensity) -{ - _waterfallData->SetFloorValue(minIntensity); - _waterfallData->setMinZ(0); - _waterfallData->setMaxZ(maxIntensity-minIntensity); - - _createCoordinateSystemFlag = true; - - emit UpdatedLowerIntensityLevel(minIntensity); - emit UpdatedUpperIntensityLevel(maxIntensity); - - SetIntensityColorMapType(_intensityColorMapType, - _userDefinedLowIntensityColor, - _userDefinedLowIntensityColor, true); -} - -void -Waterfall3DDisplayPlot::replot() -{ - if(!_initialized){ - Init(); - } - if(initializedGL()){ - const timespec startTime = get_highres_clock(); - - _waterfallData->create(); - - legend()->setMajors(4); - legend()->setMinors(5); - double start, stop; - coordinates()->axes[Qwt3D::Z1].limits(start,stop); - legend()->setLimits( _waterfallData->GetFloorValue(), _waterfallData->GetFloorValue() + stop - start ); - - coordinates()->axes[Qwt3D::X1].limits(start,stop); - - showColorLegend(true); - - updateGL(); - - double differenceTime = (diff_timespec(get_highres_clock(), startTime)); - - // Require at least a 20% duty cycle - differenceTime *= 4.0; - if(differenceTime > (1.0/5.0)){ - _displayIntervalTime = differenceTime; - } - } -} - -void -Waterfall3DDisplayPlot::resizeSlot( QSize *s ) -{ - resize(s->width(), s->height()); -} - -int -Waterfall3DDisplayPlot::GetIntensityColorMapType() const -{ - return _intensityColorMapType; -} - -void -Waterfall3DDisplayPlot::SetIntensityColorMapType(const int newType, - const QColor lowColor, - const QColor highColor, - const bool forceFlag, - const bool noReplotFlag) -{ - if(((_intensityColorMapType != newType) || forceFlag) || - ((newType == INTENSITY_COLOR_MAP_TYPE_USER_DEFINED) && - (lowColor.isValid() && highColor.isValid()))){ - - Waterfall3DColorMap* colorMap = new Waterfall3DColorMap(); - colorMap->SetInterval(_waterfallData->minZ(), _waterfallData->maxZ()); - - switch(newType){ - case INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR:{ - _intensityColorMapType = newType; - colorMap->setColorInterval(Qt::darkCyan, Qt::white); - colorMap->addColorStop(0.25, Qt::cyan); - colorMap->addColorStop(0.5, Qt::yellow); - colorMap->addColorStop(0.75, Qt::red); - setBackgroundColor(Qwt3D::Qt2GL(Qt::gray)); - break; - } - case INTENSITY_COLOR_MAP_TYPE_WHITE_HOT:{ - _intensityColorMapType = newType; - colorMap->setColorInterval(Qt::black, Qt::white); - setBackgroundColor(Qwt3D::Qt2GL(Qt::blue)); - break; - } - case INTENSITY_COLOR_MAP_TYPE_BLACK_HOT:{ - _intensityColorMapType = newType; - colorMap->setColorInterval(Qt::white, Qt::black); - setBackgroundColor(Qwt3D::Qt2GL(Qt::blue)); - break; - } - case INTENSITY_COLOR_MAP_TYPE_INCANDESCENT:{ - _intensityColorMapType = newType; - colorMap->setColorInterval(Qt::black, Qt::white); - colorMap->addColorStop(0.5, Qt::darkRed); - setBackgroundColor(Qwt3D::Qt2GL(Qt::gray)); - break; - } - case INTENSITY_COLOR_MAP_TYPE_USER_DEFINED:{ - _userDefinedLowIntensityColor = lowColor; - _userDefinedHighIntensityColor = highColor; - _intensityColorMapType = newType; - colorMap->setColorInterval(_userDefinedLowIntensityColor, _userDefinedHighIntensityColor); - setBackgroundColor(Qwt3D::Qt2GL(Qt::white)); - break; - } - default: - colorMap->setColorInterval(Qt::black, Qt::white); - break; - } - - // Qwt3D takes over destruction of this object... - setDataColor(colorMap); - - if(!noReplotFlag){ - // Draw again - replot(); - - // Update the last replot timer - _lastReplot = get_highres_clock(); - } - } -} - -const QColor -Waterfall3DDisplayPlot::GetUserDefinedLowIntensityColor() const -{ - return _userDefinedLowIntensityColor; -} - -const QColor -Waterfall3DDisplayPlot::GetUserDefinedHighIntensityColor() const -{ - return _userDefinedHighIntensityColor; -} - -#endif /* WATERFALL_3D_DISPLAY_PLOT_C */ diff --git a/gr-qtgui/src/lib/Waterfall3DDisplayPlot.h b/gr-qtgui/src/lib/Waterfall3DDisplayPlot.h deleted file mode 100644 index 272bdf697..000000000 --- a/gr-qtgui/src/lib/Waterfall3DDisplayPlot.h +++ /dev/null @@ -1,206 +0,0 @@ -#ifndef WATERFALL_3D_DISPLAY_PLOT_HPP -#define WATERFALL_3D_DISPLAY_PLOT_HPP - -#include <cstdio> -#include <highResTimeFunctions.h> - -#include <waterfallGlobalData.h> -#include <qwt3d_surfaceplot.h> - -#include <qwt3d_color.h> -#include <qwt_color_map.h> - -class Waterfall3DColorMap: public Qwt3D::Color, public QwtLinearColorMap -{ -public: - Waterfall3DColorMap(); - virtual ~Waterfall3DColorMap(); - - virtual Qwt3D::RGBA operator()(double x, double y, double z)const; - virtual Qwt3D::ColorVector& createVector(Qwt3D::ColorVector& vec); - - virtual void SetInterval(const double minValue, const double maxValue); - -protected: - -private: - QwtDoubleInterval _interval; -}; - -class Waterfall3DDisplayPlot:public Qwt3D::SurfacePlot{ - Q_OBJECT - - protected: - class IntensityScale:public Qwt3D::LinearScale{ - - friend class Qwt3D::Axis; - friend class Qwt3D::qwt3d_ptr<Qwt3D::Scale>; - - private: - double _floor; - - public: - explicit IntensityScale(const double newFloor):_floor(newFloor){ } - virtual ~IntensityScale(){} - - virtual QString ticLabel(unsigned int idx) const{ - if (idx<majors_p.size()) - { - return QString("%1").arg( majors_p[idx] + GetFloorValue(), 0, 'f', 0 ); - } - return QString(""); - } - - virtual double GetFloorValue()const{ return _floor; } - virtual void SetFloorValue(const double newFloor){ _floor = newFloor; } - - //! Returns a new heap based object utilized from qwt3d_ptr - Scale* clone() const {return new IntensityScale(*this);} - }; - - class TimeScale:public Qwt3D::LinearScale{ - - friend class Qwt3D::Axis; - friend class Qwt3D::qwt3d_ptr<Qwt3D::Scale>; - friend class Waterfall3DDisplayPlot; - - private: - Waterfall3DDisplayPlot* _plot; - - public: - TimeScale(Waterfall3DDisplayPlot* plot ):_plot(plot){ - } - virtual ~TimeScale(){ - } - - virtual QString ticLabel(unsigned int idx) const{ - if (idx<majors_p.size()) - { - const timespec markerTime = timespec_add(_plot->_dataTimestamp, - -(_plot->_timePerFFT) * majors_p[idx]); - struct tm timeTm; - gmtime_r(&markerTime.tv_sec, &timeTm); - - char* timeBuffer = new char[128]; - snprintf(timeBuffer, 128, "%02d:%02d:%02d.%03ld", timeTm.tm_hour, - timeTm.tm_min, timeTm.tm_sec, (markerTime.tv_nsec / 1000000)); - QString returnBuffer(timeBuffer); - delete[] timeBuffer; - return returnBuffer; - } - return QString(""); - } - - //! Returns a new heap based object utilized from qwt3d_ptr - Scale* clone() const {return new TimeScale(*this);} - }; - - class FrequencyScale: public Qwt3D::LinearScale{ - - friend class Qwt3D::Axis; - friend class Qwt3D::qwt3d_ptr<Qwt3D::Scale>; - private: - double _centerFrequency; - bool _useCenterFrequencyFlag; - public: - FrequencyScale(bool useCenterFrequencyFlag, double centerFrequency) - : _centerFrequency(centerFrequency),_useCenterFrequencyFlag(useCenterFrequencyFlag) - {} - - virtual ~FrequencyScale(){} - - virtual QString ticLabel(unsigned int idx) const - { - if (idx<majors_p.size()) - { - if(!_useCenterFrequencyFlag){ - return QString("%1").arg( majors_p[idx], 0, 'f', 0 ); - - } - else{ - return QString("%1").arg( (majors_p[idx] + _centerFrequency)/1000.0, 0, 'f', 3 ); - } - } - return QString(""); - } - - //! Returns a new heap based object utilized from qwt3d_ptr - Scale* clone() const {return new FrequencyScale(*this);} - }; - -public: - Waterfall3DDisplayPlot(QWidget*); - virtual ~Waterfall3DDisplayPlot(); - - void Init(); - void Reset(); - - 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, - const double units, const std::string &strunits); - 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 SetIntensityRange(const double minIntensity, const double maxIntensity); - - virtual void replot(void); - - int GetIntensityColorMapType()const; - void SetIntensityColorMapType( const int, const QColor, - const QColor, const bool forceFlag = false, - const bool noReplotFlag = false ); - const QColor GetUserDefinedLowIntensityColor()const; - const QColor GetUserDefinedHighIntensityColor()const; - - static const int INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR = 0; - static const int INTENSITY_COLOR_MAP_TYPE_WHITE_HOT = 1; - static const int INTENSITY_COLOR_MAP_TYPE_BLACK_HOT = 2; - static const int INTENSITY_COLOR_MAP_TYPE_INCANDESCENT = 3; - static const int INTENSITY_COLOR_MAP_TYPE_USER_DEFINED = 4; - -public slots: - void resizeSlot( QSize *s ); - - -signals: - void UpdatedLowerIntensityLevel(const double); - void UpdatedUpperIntensityLevel(const double); - -protected: - - double _startFrequency; - double _stopFrequency; - - Waterfall3DData* _waterfallData; - - timespec _lastReplot; - - int64_t _numPoints; - - double _displayIntervalTime; - - int _intensityColorMapType; - QColor _userDefinedLowIntensityColor; - QColor _userDefinedHighIntensityColor; - - bool _useCenterFrequencyFlag; - double _centerFrequency; - - timespec _dataTimestamp; - double _timePerFFT; - bool _initialized; - - bool _createCoordinateSystemFlag; - -private: - -}; - -#endif /* WATERFALL_3D_DISPLAY_PLOT_HPP */ diff --git a/gr-qtgui/src/lib/WaterfallDisplayPlot.cc b/gr-qtgui/src/lib/WaterfallDisplayPlot.cc index f6d0cc0ba..680c44756 100644 --- a/gr-qtgui/src/lib/WaterfallDisplayPlot.cc +++ b/gr-qtgui/src/lib/WaterfallDisplayPlot.cc @@ -66,8 +66,7 @@ public: QwtText label(double value) const { - return QString("%1").arg((value + GetCenterFrequency()) / ((GetFrequencyPrecision() == 0) ? 1.0 : 1000.0), - 0, 'f', GetFrequencyPrecision()); + return QString("%1").arg(value, 0, 'f', GetFrequencyPrecision()); } virtual void initiateUpdate() @@ -161,7 +160,8 @@ private: }; -class WaterfallZoomer: public QwtPlotZoomer, public TimeScaleData, public FreqOffsetAndPrecisionClass +class WaterfallZoomer: public QwtPlotZoomer, public TimeScaleData, + public FreqOffsetAndPrecisionClass { public: WaterfallZoomer(QwtPlotCanvas* canvas, const unsigned int freqPrecision) @@ -180,7 +180,13 @@ public: updateDisplay(); } + void SetUnitType(const std::string &type) + { + _unitType = type; + } + protected: + using QwtPlotZoomer::trackerText; virtual QwtText trackerText( const QwtDoublePoint& p ) const { QString yLabel(""); @@ -193,10 +199,14 @@ protected: timeTm.tm_mday, timeTm.tm_hour, timeTm.tm_min, timeTm.tm_sec, lineTime.tv_nsec/1000000)); - QwtText t(QString("%1 %2, %3").arg((p.x() + GetCenterFrequency()) / ((GetFrequencyPrecision() == 0) ? 1.0 : 1000.0), 0, 'f', GetFrequencyPrecision()).arg( (GetFrequencyPrecision() == 0) ? "Hz" : "kHz").arg(yLabel)); - + QwtText t(QString("%1 %2, %3"). + arg(p.x(), 0, 'f', GetFrequencyPrecision()). + arg(_unitType.c_str()).arg(yLabel)); return t; } + +private: + std::string _unitType; }; @@ -216,8 +226,6 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent) resize(parent->width(), parent->height()); _numPoints = 1024; - _displayIntervalTime = (1.0/5.0); // 1/5 of a second between updates - _waterfallData = new WaterfallData(_startFrequency, _stopFrequency, _numPoints, 200); QPalette palette; @@ -282,6 +290,7 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent) WaterfallDisplayPlot::~WaterfallDisplayPlot() { delete _waterfallData; + delete d_spectrogram; } void @@ -290,6 +299,8 @@ WaterfallDisplayPlot::Reset() _waterfallData->ResizeData(_startFrequency, _stopFrequency, _numPoints); _waterfallData->Reset(); + setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency); + // Load up the new base zoom settings QwtDoubleRect newSize = _zoomer->zoomBase(); newSize.setLeft(_startFrequency); @@ -310,27 +321,32 @@ WaterfallDisplayPlot::SetFrequencyRange(const double constStartFreq, double stopFreq = constStopFreq / units; double centerFreq = constCenterFreq / units; - if(stopFreq > startFreq) { - _startFrequency = 1000*startFreq; - _stopFrequency = 1000*stopFreq; + _useCenterFrequencyFlag = useCenterFrequencyFlag; - setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency); + if(_useCenterFrequencyFlag){ + startFreq = (startFreq + centerFreq); + stopFreq = (stopFreq + centerFreq); + } - if((axisScaleDraw(QwtPlot::xBottom) != NULL) && (_zoomer != NULL)){ - WaterfallFreqDisplayScaleDraw* freqScale = ((WaterfallFreqDisplayScaleDraw*)axisScaleDraw(QwtPlot::xBottom)); - freqScale->SetCenterFrequency(centerFreq); - ((WaterfallZoomer*)_zoomer)->SetCenterFrequency(centerFreq); + bool reset = false; + if((startFreq != _startFrequency) || (stopFreq != _stopFrequency)) + reset = true; - freqScale->SetFrequencyPrecision( 2 ); - ((WaterfallZoomer*)_zoomer)->SetFrequencyPrecision( 2 ); + if(stopFreq > startFreq) { + _startFrequency = startFreq; + _stopFrequency = stopFreq; + + if((axisScaleDraw(QwtPlot::xBottom) != NULL) && (_zoomer != NULL)){ + double display_units = ceil(log10(units)/2.0); + setAxisScaleDraw(QwtPlot::xBottom, new WaterfallFreqDisplayScaleDraw(display_units)); setAxisTitle(QwtPlot::xBottom, QString("Frequency (%1)").arg(strunits.c_str())); - } - Reset(); + if(reset) { + Reset(); + } - // Only replot if screen is visible - if(isVisible()){ - replot(); + ((WaterfallZoomer*)_zoomer)->SetFrequencyPrecision(display_units); + ((WaterfallZoomer*)_zoomer)->SetUnitType(strunits); } } } @@ -350,50 +366,46 @@ WaterfallDisplayPlot::GetStopFrequency() const void WaterfallDisplayPlot::PlotNewData(const double* dataPoints, - const int64_t numDataPoints, - const double timePerFFT, - const timespec timestamp, - const int droppedFrames) + const int64_t numDataPoints, + const double timePerFFT, + const timespec timestamp, + const int droppedFrames) { if(numDataPoints > 0){ if(numDataPoints != _numPoints){ _numPoints = numDataPoints; - + Reset(); - + d_spectrogram->invalidateCache(); d_spectrogram->itemChanged(); - + if(isVisible()){ replot(); } - + _lastReplot = get_highres_clock(); } - _waterfallData->addFFTData(dataPoints, numDataPoints, droppedFrames); - _waterfallData->IncrementNumLinesToUpdate(); - - QwtTimeScaleDraw* timeScale = (QwtTimeScaleDraw*)axisScaleDraw(QwtPlot::yLeft); - timeScale->SetSecondsPerLine(timePerFFT); - timeScale->SetZeroTime(timestamp); - - ((WaterfallZoomer*)_zoomer)->SetSecondsPerLine(timePerFFT); - ((WaterfallZoomer*)_zoomer)->SetZeroTime(timestamp); - } - - // Allow at least a 50% duty cycle - if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){ - - d_spectrogram->invalidateCache(); - d_spectrogram->itemChanged(); - - // Only update when window is visible - if(isVisible()){ + if(diff_timespec(get_highres_clock(), _lastReplot) > timePerFFT) { + //FIXME: We may want to average the data between these updates to smooth display + _waterfallData->addFFTData(dataPoints, numDataPoints, droppedFrames); + _waterfallData->IncrementNumLinesToUpdate(); + + QwtTimeScaleDraw* timeScale = (QwtTimeScaleDraw*)axisScaleDraw(QwtPlot::yLeft); + timeScale->SetSecondsPerLine(timePerFFT); + timeScale->SetZeroTime(timestamp); + + ((WaterfallZoomer*)_zoomer)->SetSecondsPerLine(timePerFFT); + ((WaterfallZoomer*)_zoomer)->SetZeroTime(timestamp); + + d_spectrogram->invalidateCache(); + d_spectrogram->itemChanged(); + replot(); - } - _lastReplot = get_highres_clock(); + _lastReplot = get_highres_clock(); + } } } @@ -412,8 +424,6 @@ WaterfallDisplayPlot::SetIntensityRange(const double minIntensity, void WaterfallDisplayPlot::replot() { - const timespec startTime = get_highres_clock(); - QwtTimeScaleDraw* timeScale = (QwtTimeScaleDraw*)axisScaleDraw(QwtPlot::yLeft); timeScale->initiateUpdate(); @@ -435,14 +445,6 @@ WaterfallDisplayPlot::replot() } QwtPlot::replot(); - - double differenceTime = (diff_timespec(get_highres_clock(), startTime)); - - // Require at least a 5% duty cycle - differenceTime *= 19.0; - if(differenceTime > (1.0/5.0)){ - _displayIntervalTime = differenceTime; - } } void diff --git a/gr-qtgui/src/lib/WaterfallDisplayPlot.h b/gr-qtgui/src/lib/WaterfallDisplayPlot.h index bb87fb09f..a5ccaec40 100644 --- a/gr-qtgui/src/lib/WaterfallDisplayPlot.h +++ b/gr-qtgui/src/lib/WaterfallDisplayPlot.h @@ -69,9 +69,9 @@ private: timespec _lastReplot; - int64_t _numPoints; + bool _useCenterFrequencyFlag; - double _displayIntervalTime; + int64_t _numPoints; int _intensityColorMapType; QColor _userDefinedLowIntensityColor; diff --git a/gr-qtgui/src/lib/highResTimeFunctions.h b/gr-qtgui/src/lib/highResTimeFunctions.h index b85b1acad..251bbad8b 100644 --- a/gr-qtgui/src/lib/highResTimeFunctions.h +++ b/gr-qtgui/src/lib/highResTimeFunctions.h @@ -8,41 +8,74 @@ static const long NSEC_PER_SEC = 1000000000L; -static inline bool timespec_greater(const struct timespec* t1, const struct timespec* t0){ - return ((t1->tv_sec > t0->tv_sec) || ((t1->tv_sec == t0->tv_sec) && (t1->tv_nsec > t0->tv_nsec))); +static inline bool +timespec_greater(const struct timespec* t1, + const struct timespec* t0) +{ + return ((t1->tv_sec > t0->tv_sec) || + ((t1->tv_sec == t0->tv_sec) && + (t1->tv_nsec > t0->tv_nsec))); } -static inline bool timespec_greater(const struct timespec t1, const struct timespec t0){ - return ((t1.tv_sec > t0.tv_sec) || ((t1.tv_sec == t0.tv_sec) && (t1.tv_nsec > t0.tv_nsec))); +static inline bool +timespec_greater(const struct timespec t1, + const struct timespec t0) +{ + return ((t1.tv_sec > t0.tv_sec) || + ((t1.tv_sec == t0.tv_sec) && + (t1.tv_nsec > t0.tv_nsec))); } -static inline bool timespec_less(const struct timespec* t1, const struct timespec* t0){ - return ((t1->tv_sec < t0->tv_sec) || ((t1->tv_sec == t0->tv_sec) && (t1->tv_nsec < t0->tv_nsec))); +static inline bool +timespec_less(const struct timespec* t1, + const struct timespec* t0) +{ + return ((t1->tv_sec < t0->tv_sec) || + ((t1->tv_sec == t0->tv_sec) && + (t1->tv_nsec < t0->tv_nsec))); } -static inline bool timespec_less(const struct timespec t1, const struct timespec t0){ - return ((t1.tv_sec < t0.tv_sec) || ((t1.tv_sec == t0.tv_sec) && (t1.tv_nsec < t0.tv_nsec))); +static inline bool +timespec_less(const struct timespec t1, + const struct timespec t0) +{ + return ((t1.tv_sec < t0.tv_sec) || + ((t1.tv_sec == t0.tv_sec) && + (t1.tv_nsec < t0.tv_nsec))); } -static inline bool timespec_equal(const struct timespec* t1, const struct timespec* t0){ - return ((t1->tv_sec == t0->tv_sec) && (t1->tv_nsec == t0->tv_nsec)); +static inline bool +timespec_equal(const struct timespec* t1, + const struct timespec* t0) +{ + return ((t1->tv_sec == t0->tv_sec) && + (t1->tv_nsec == t0->tv_nsec)); } -static inline bool timespec_equal(const struct timespec t1, const struct timespec t0){ - return ((t1.tv_sec == t0.tv_sec) && (t1.tv_nsec == t0.tv_nsec)); +static inline bool +timespec_equal(const struct timespec t1, + const struct timespec t0) +{ + return ((t1.tv_sec == t0.tv_sec) && + (t1.tv_nsec == t0.tv_nsec)); } -static inline void timespec_reset(struct timespec* ret){ +static inline void +timespec_reset(struct timespec* ret) +{ ret->tv_sec = 0; ret->tv_nsec = 0; } -static inline void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec){ - while (nsec > NSEC_PER_SEC){ +static inline void +set_normalized_timespec(struct timespec *ts, + time_t sec, long nsec) +{ + while (nsec > NSEC_PER_SEC) { nsec -= NSEC_PER_SEC; ++sec; } - while(nsec < 0){ + while(nsec < 0) { nsec += NSEC_PER_SEC; --sec; } @@ -50,10 +83,13 @@ static inline void set_normalized_timespec(struct timespec *ts, time_t sec, long ts->tv_nsec = nsec; } -static inline struct timespec convert_to_timespec(const double timeValue){ +static inline struct timespec +convert_to_timespec(const double timeValue) +{ struct timespec ret; double seconds = 0; - long nsec = static_cast<long>(modf(timeValue, &seconds) * static_cast<double>(NSEC_PER_SEC)); + long nsec = static_cast<long>(modf(timeValue, &seconds) * + static_cast<double>(NSEC_PER_SEC)); time_t sec = static_cast<time_t>(seconds); set_normalized_timespec(&ret, sec, nsec); @@ -61,28 +97,46 @@ static inline struct timespec convert_to_timespec(const double timeValue){ return ret; } -static inline double convert_from_timespec(const timespec actual){ - return (static_cast<double>(actual.tv_sec) + (static_cast<double>(actual.tv_nsec) / static_cast<double>(NSEC_PER_SEC))); +static inline double +convert_from_timespec(const timespec actual) +{ + return (static_cast<double>(actual.tv_sec) + + (static_cast<double>(actual.tv_nsec) / + static_cast<double>(NSEC_PER_SEC))); } -static inline void timespec_add(struct timespec *ret, const struct timespec* t1, const struct timespec* t0){ +static inline void +timespec_add(struct timespec *ret, + const struct timespec* t1, + const struct timespec* t0) +{ time_t sec = t1->tv_sec + t0->tv_sec; long nsec = t1->tv_nsec + t0->tv_nsec; set_normalized_timespec(ret, sec, nsec); } -static inline void timespec_add(struct timespec *ret, const struct timespec t1, const struct timespec t0){ +static inline void +timespec_add(struct timespec *ret, + const struct timespec t1, + const struct timespec t0) +{ return timespec_add(ret, &t1, &t0); } -static inline struct timespec timespec_add(const struct timespec t1, const struct timespec t0){ +static inline struct timespec +timespec_add(const struct timespec t1, + const struct timespec t0) +{ struct timespec ret; timespec_add(&ret, &t1, &t0); return ret; } -static inline struct timespec timespec_add(const struct timespec t1, const double time0){ +static inline struct timespec +timespec_add(const struct timespec t1, + const double time0) +{ struct timespec ret; struct timespec t0; t0 = convert_to_timespec(time0); @@ -92,24 +146,38 @@ static inline struct timespec timespec_add(const struct timespec t1, const doubl return ret; } -static inline void timespec_subtract(struct timespec *ret, const struct timespec* t1, const struct timespec* t0){ +static inline void +timespec_subtract(struct timespec *ret, + const struct timespec* t1, + const struct timespec* t0) +{ time_t sec = t1->tv_sec - t0->tv_sec; long nsec = t1->tv_nsec - t0->tv_nsec; set_normalized_timespec(ret, sec, nsec); } -static inline void timespec_subtract(struct timespec *ret, const struct timespec t1, const struct timespec t0){ +static inline void +timespec_subtract(struct timespec *ret, + const struct timespec t1, + const struct timespec t0) +{ return timespec_subtract(ret, &t1, &t0); } -static inline struct timespec timespec_subtract(const struct timespec t1, const struct timespec t0){ +static inline struct timespec +timespec_subtract(const struct timespec t1, + const struct timespec t0) +{ struct timespec ret; timespec_subtract(&ret, &t1, &t0); return ret; } -static inline struct timespec timespec_subtract(const struct timespec t1, const double time0){ +static inline struct timespec +timespec_subtract(const struct timespec t1, + const double time0) +{ struct timespec ret; struct timespec t0; t0 = convert_to_timespec(time0); @@ -119,7 +187,11 @@ static inline struct timespec timespec_subtract(const struct timespec t1, const return ret; } -static inline double diff_timespec(struct timespec* ret, const struct timespec *t1, const struct timespec* t0){ +static inline double +diff_timespec(struct timespec* ret, + const struct timespec *t1, + const struct timespec* t0) +{ struct timespec actual; time_t sec = 0; long nsec = 0; @@ -141,7 +213,8 @@ static inline double diff_timespec(struct timespec* ret, const struct timespec * sec = t0->tv_sec - t1->tv_sec; nsec = t0->tv_nsec - t1->tv_nsec; - // Do nothing with the ret value as the ret value would have to store a negative, which it can't. + // Do nothing with the ret value as the ret value + // would have to store a negative, which it can't. set_normalized_timespec(&actual, sec, nsec); @@ -149,23 +222,39 @@ static inline double diff_timespec(struct timespec* ret, const struct timespec * } } -static inline double diff_timespec(struct timespec* ret, const struct timespec t1, const struct timespec t0){ +static inline double +diff_timespec(struct timespec* ret, + const struct timespec t1, + const struct timespec t0) +{ return diff_timespec(ret, &t1, &t0); } -static inline double diff_timespec(const struct timespec t1, const struct timespec t0){ +static inline double +diff_timespec(const struct timespec t1, + const struct timespec t0) +{ return diff_timespec(NULL, &t1, &t0); } -static inline double diff_timespec(const struct timespec* t1, const struct timespec* t0){ +static inline double +diff_timespec(const struct timespec* t1, + const struct timespec* t0) +{ return diff_timespec(NULL, t1, t0); } -static inline void get_highres_clock(struct timespec* ret){ +#ifdef CLOCK_REALTIME +// If we can use clock_gettime, use it; +// otherwise, use gettimeofday +static inline void +get_highres_clock(struct timespec* ret) +{ if(clock_gettime(CLOCK_REALTIME, ret) != 0){ - // Unable to get high resolution time - fail over to low resolution time + // Unable to get high resolution time - + // fail over to low resolution time timeval lowResTime; gettimeofday(&lowResTime, NULL); ret->tv_sec = lowResTime.tv_sec; @@ -173,17 +262,37 @@ static inline void get_highres_clock(struct timespec* ret){ } } -static inline struct timespec get_highres_clock(){ +#else + +// Trick timer functions into thinking it has an nsec timer +// but only use the low resolution (usec) timer. +static inline void +get_highres_clock(struct timespec* ret) +{ + timeval lowResTime; + gettimeofday(&lowResTime, NULL); + ret->tv_sec = lowResTime.tv_sec; + ret->tv_nsec = lowResTime.tv_usec*1000; +} +#endif + +static inline struct timespec +get_highres_clock() +{ struct timespec ret; get_highres_clock(&ret); return ret; } -static inline bool timespec_empty(const struct timespec* ret){ +static inline bool +timespec_empty(const struct timespec* ret) +{ return ( (ret->tv_sec == 0 ) && (ret->tv_nsec == 0) ); } -static inline bool timespec_empty(const struct timespec ret){ +static inline bool +timespec_empty(const struct timespec ret) +{ return timespec_empty(&ret); } diff --git a/gr-qtgui/src/lib/qtgui_sink_c.cc b/gr-qtgui/src/lib/qtgui_sink_c.cc index 7340141a6..c12c451b0 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,2009 Free Software Foundation, Inc. + * Copyright 2008,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -40,7 +40,7 @@ qtgui_make_sink_c (int fftsize, int wintype, bool use_openGL, QWidget *parent) { - return qtgui_sink_c_sptr (new qtgui_sink_c (fftsize, wintype, + return gnuradio::get_initial_sptr(new qtgui_sink_c (fftsize, wintype, fc, bw, name, plotfreq, plotwaterfall, plotwaterfall3d, plottime, @@ -64,10 +64,13 @@ qtgui_sink_c::qtgui_sink_c (int fftsize, int wintype, d_wintype((gr_firdes::win_type)(wintype)), d_center_freq(fc), d_bandwidth(bw), d_name(name), d_plotfreq(plotfreq), d_plotwaterfall(plotwaterfall), - d_plotwaterfall3d(plotwaterfall3d), d_plottime(plottime), - d_plotconst(plotconst), + d_plottime(plottime), d_plotconst(plotconst), d_parent(parent) { + if(plotwaterfall3d == true) { + fprintf(stderr, "Warning: plotting Waterfall3D has been removed; enabling plotwaterfall3d has no effect.\n"); + } + d_main_gui = NULL; pthread_mutex_init(&d_pmutex, NULL); lock(); @@ -88,7 +91,7 @@ qtgui_sink_c::qtgui_sink_c (int fftsize, int wintype, qtgui_sink_c::~qtgui_sink_c() { - delete d_object; + delete d_main_gui; delete [] d_residbuf; delete d_fft; } @@ -141,10 +144,12 @@ qtgui_sink_c::initialize(const bool opengl) d_main_gui->OpenSpectrumWindow(d_parent, d_plotfreq, d_plotwaterfall, - d_plotwaterfall3d, d_plottime, - d_plotconst, + d_plottime, d_plotconst, opengl); + // initialize update time to 10 times a second + set_update_time(0.1); + d_object = new qtgui_obj(d_qApplication); qApp->postEvent(d_object, new qtgui_event(&d_pmutex)); } @@ -208,6 +213,13 @@ qtgui_sink_c::set_frequency_axis(double min, double max) } void +qtgui_sink_c::set_update_time(double t) +{ + d_update_time = t; + d_main_gui->SetUpdateTime(d_update_time); +} + +void qtgui_sink_c::fft(const gr_complex *data_in, int size) { if (d_window.size()) { @@ -300,7 +312,7 @@ qtgui_sink_c::general_work (int noutput_items, d_main_gui->UpdateWindow(true, d_fft->get_outbuf(), d_fftsize, NULL, 0, (float*)d_residbuf, d_fftsize, - 1.0/4.0, currentTime, true); + currentTime, true); } // Otherwise, copy what we received into the residbuf for next time else { diff --git a/gr-qtgui/src/lib/qtgui_sink_c.h b/gr-qtgui/src/lib/qtgui_sink_c.h index 91c6b03e6..9aee66503 100644 --- a/gr-qtgui/src/lib/qtgui_sink_c.h +++ b/gr-qtgui/src/lib/qtgui_sink_c.h @@ -23,12 +23,12 @@ #ifndef INCLUDED_QTGUI_SINK_C_H #define INCLUDED_QTGUI_SINK_C_H +#include <Python.h> #include <gr_block.h> #include <gr_firdes.h> #include <gri_fft.h> #include <qapplication.h> #include <qtgui.h> -#include <Python.h> #include "SpectrumGUIClass.h" class qtgui_sink_c; @@ -84,8 +84,10 @@ private: int d_index; gr_complex *d_residbuf; - bool d_plotfreq, d_plotwaterfall, d_plotwaterfall3d, d_plottime, d_plotconst; + bool d_plotfreq, d_plotwaterfall, d_plottime, d_plotconst; + double d_update_time; + QWidget *d_parent; SpectrumGUIClass *d_main_gui; @@ -111,6 +113,8 @@ public: void set_constellation_pen_size(int size); void set_frequency_axis(double min, double max); + void set_update_time(double t); + 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 6fbb2f381..ab4fd082d 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,2009 Free Software Foundation, Inc. + * Copyright 2008,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -40,7 +40,7 @@ qtgui_make_sink_f (int fftsize, int wintype, bool use_openGL, QWidget *parent) { - return qtgui_sink_f_sptr (new qtgui_sink_f (fftsize, wintype, + return gnuradio::get_initial_sptr(new qtgui_sink_f (fftsize, wintype, fc, bw, name, plotfreq, plotwaterfall, plotwaterfall3d, plottime, @@ -64,10 +64,13 @@ qtgui_sink_f::qtgui_sink_f (int fftsize, int wintype, d_wintype((gr_firdes::win_type)(wintype)), d_center_freq(fc), d_bandwidth(bw), d_name(name), d_plotfreq(plotfreq), d_plotwaterfall(plotwaterfall), - d_plotwaterfall3d(plotwaterfall3d), d_plottime(plottime), - d_plotconst(plotconst), + d_plottime(plottime), d_plotconst(plotconst), d_parent(parent) { + if(plotwaterfall3d == true) { + fprintf(stderr, "Warning: plotting Waterfall3D has been removed; enabling plotwaterfall3d has no effect.\n"); + } + d_main_gui = NULL; pthread_mutex_init(&d_pmutex, NULL); lock(); @@ -88,7 +91,7 @@ qtgui_sink_f::qtgui_sink_f (int fftsize, int wintype, qtgui_sink_f::~qtgui_sink_f() { - delete d_object; + delete d_main_gui; delete [] d_residbuf; delete d_fft; } @@ -136,10 +139,12 @@ qtgui_sink_f::initialize(const bool opengl) d_main_gui->OpenSpectrumWindow(d_parent, d_plotfreq, d_plotwaterfall, - d_plotwaterfall3d, d_plottime, - d_plotconst, + d_plottime, d_plotconst, opengl); + // initialize update time to 10 times a second + set_update_time(0.1); + d_object = new qtgui_obj(d_qApplication); qApp->postEvent(d_object, new qtgui_event(&d_pmutex)); } @@ -202,6 +207,13 @@ qtgui_sink_f::set_frequency_axis(double min, double max) } void +qtgui_sink_f::set_update_time(double t) +{ + d_update_time = t; + d_main_gui->SetUpdateTime(d_update_time); +} + +void qtgui_sink_f::fft(const float *data_in, int size) { if (d_window.size()) { @@ -295,7 +307,7 @@ qtgui_sink_f::general_work (int noutput_items, d_main_gui->UpdateWindow(true, d_fft->get_outbuf(), d_fftsize, (float*)d_residbuf, d_fftsize, NULL, 0, - 1.0/4.0, currentTime, true); + currentTime, true); } // Otherwise, copy what we received into the residbuf for next time else { diff --git a/gr-qtgui/src/lib/qtgui_sink_f.h b/gr-qtgui/src/lib/qtgui_sink_f.h index 47c928d17..0cac35d90 100644 --- a/gr-qtgui/src/lib/qtgui_sink_f.h +++ b/gr-qtgui/src/lib/qtgui_sink_f.h @@ -23,12 +23,12 @@ #ifndef INCLUDED_QTGUI_SINK_F_H #define INCLUDED_QTGUI_SINK_F_H +#include <Python.h> #include <gr_block.h> #include <gr_firdes.h> #include <gri_fft.h> #include <qapplication.h> #include <qtgui.h> -#include <Python.h> #include "SpectrumGUIClass.h" class qtgui_sink_f; @@ -82,7 +82,9 @@ private: int d_index; float *d_residbuf; - bool d_plotfreq, d_plotwaterfall, d_plotwaterfall3d, d_plottime, d_plotconst; + bool d_plotfreq, d_plotwaterfall, d_plottime, d_plotconst; + + double d_update_time; QWidget *d_parent; SpectrumGUIClass *d_main_gui; @@ -109,6 +111,8 @@ public: void set_constellation_pen_size(int size); void set_frequency_axis(double min, double max); + void set_update_time(double t); + QApplication *d_qApplication; qtgui_obj *d_object; diff --git a/gr-qtgui/src/lib/spectrumUpdateEvents.cc b/gr-qtgui/src/lib/spectrumUpdateEvents.cc index 2da37d350..53a205fb7 100644 --- a/gr-qtgui/src/lib/spectrumUpdateEvents.cc +++ b/gr-qtgui/src/lib/spectrumUpdateEvents.cc @@ -8,7 +8,6 @@ SpectrumUpdateEvent::SpectrumUpdateEvent(const std::complex<float>* fftPoints, const double* realTimeDomainPoints, const double* imagTimeDomainPoints, const uint64_t numTimeDomainDataPoints, - const double timePerFFT, const timespec dataTimestamp, const bool repeatDataFlag, const bool lastOfMultipleUpdateFlag, @@ -16,15 +15,19 @@ SpectrumUpdateEvent::SpectrumUpdateEvent(const std::complex<float>* fftPoints, const int droppedFFTFrames) : QEvent(QEvent::Type(10005)) { - _numFFTDataPoints = numFFTDataPoints; - if(_numFFTDataPoints < 1){ + if(numFFTDataPoints < 1) { _numFFTDataPoints = 1; } + else { + _numFFTDataPoints = numFFTDataPoints; + } - _numTimeDomainDataPoints = numTimeDomainDataPoints; - if(_numTimeDomainDataPoints < 1){ + if(numTimeDomainDataPoints < 1) { _numTimeDomainDataPoints = 1; } + else { + _numTimeDomainDataPoints = numTimeDomainDataPoints; + } _fftPoints = new std::complex<float>[_numFFTDataPoints]; _fftPoints[0] = std::complex<float>(0,0); @@ -32,26 +35,26 @@ SpectrumUpdateEvent::SpectrumUpdateEvent(const std::complex<float>* fftPoints, _realDataTimeDomainPoints = new double[_numTimeDomainDataPoints]; memset(_realDataTimeDomainPoints, 0x0, _numTimeDomainDataPoints*sizeof(double)); - if(numTimeDomainDataPoints > 0){ + if(numTimeDomainDataPoints > 0) { memcpy(_realDataTimeDomainPoints, realTimeDomainPoints, numTimeDomainDataPoints*sizeof(double)); } _imagDataTimeDomainPoints = new double[_numTimeDomainDataPoints]; memset(_imagDataTimeDomainPoints, 0x0, _numTimeDomainDataPoints*sizeof(double)); - if(numTimeDomainDataPoints > 0){ + if(numTimeDomainDataPoints > 0) { memcpy(_imagDataTimeDomainPoints, imagTimeDomainPoints, numTimeDomainDataPoints*sizeof(double)); } _dataTimestamp = dataTimestamp; - _timePerFFT = timePerFFT; _repeatDataFlag = repeatDataFlag; _lastOfMultipleUpdateFlag = lastOfMultipleUpdateFlag; _eventGeneratedTimestamp = generatedTimestamp; _droppedFFTFrames = droppedFFTFrames; } -SpectrumUpdateEvent::~SpectrumUpdateEvent(){ +SpectrumUpdateEvent::~SpectrumUpdateEvent() +{ delete[] _fftPoints; delete[] _realDataTimeDomainPoints; delete[] _imagDataTimeDomainPoints; @@ -87,12 +90,6 @@ SpectrumUpdateEvent::getNumTimeDomainDataPoints() const return _numTimeDomainDataPoints; } -double -SpectrumUpdateEvent::getTimePerFFT() const -{ - return _timePerFFT; -} - timespec SpectrumUpdateEvent::getDataTimestamp() const { diff --git a/gr-qtgui/src/lib/spectrumUpdateEvents.h b/gr-qtgui/src/lib/spectrumUpdateEvents.h index 75fa27324..ccc072c3e 100644 --- a/gr-qtgui/src/lib/spectrumUpdateEvents.h +++ b/gr-qtgui/src/lib/spectrumUpdateEvents.h @@ -10,19 +10,29 @@ class SpectrumUpdateEvent:public QEvent{ public: - SpectrumUpdateEvent(const std::complex<float>* 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); + SpectrumUpdateEvent(const std::complex<float>* fftPoints, + const uint64_t numFFTDataPoints, + const double* realTimeDomainPoints, + const double* imagTimeDomainPoints, + const uint64_t numTimeDomainDataPoints, + const timespec dataTimestamp, + const bool repeatDataFlag, + const bool lastOfMultipleUpdateFlag, + const timespec generatedTimestamp, + const int droppedFFTFrames); + ~SpectrumUpdateEvent(); - const std::complex<float>* getFFTPoints()const; - const double* getRealTimeDomainPoints()const; - const double* getImagTimeDomainPoints()const; - uint64_t getNumFFTDataPoints()const; - uint64_t getNumTimeDomainDataPoints()const; - double getTimePerFFT()const; - timespec getDataTimestamp()const; - bool getRepeatDataFlag()const; - bool getLastOfMultipleUpdateFlag()const; - timespec getEventGeneratedTimestamp()const; - int getDroppedFFTFrames()const; + + const std::complex<float>* getFFTPoints() const; + const double* getRealTimeDomainPoints() const; + const double* getImagTimeDomainPoints() const; + uint64_t getNumFFTDataPoints() const; + uint64_t getNumTimeDomainDataPoints() const; + timespec getDataTimestamp() const; + bool getRepeatDataFlag() const; + bool getLastOfMultipleUpdateFlag() const; + timespec getEventGeneratedTimestamp() const; + int getDroppedFFTFrames() const; protected: @@ -32,7 +42,6 @@ private: double* _imagDataTimeDomainPoints; uint64_t _numFFTDataPoints; uint64_t _numTimeDomainDataPoints; - double _timePerFFT; timespec _dataTimestamp; bool _repeatDataFlag; bool _lastOfMultipleUpdateFlag; diff --git a/gr-qtgui/src/lib/spectrumdisplayform.cc b/gr-qtgui/src/lib/spectrumdisplayform.cc Binary files differindex b27292193..e0509a294 100644 --- a/gr-qtgui/src/lib/spectrumdisplayform.cc +++ b/gr-qtgui/src/lib/spectrumdisplayform.cc diff --git a/gr-qtgui/src/lib/spectrumdisplayform.h b/gr-qtgui/src/lib/spectrumdisplayform.h index d89141f1e..fbd08349b 100644 --- a/gr-qtgui/src/lib/spectrumdisplayform.h +++ b/gr-qtgui/src/lib/spectrumdisplayform.h @@ -1,7 +1,7 @@ #ifndef SPECTRUM_DISPLAY_FORM_H #define SPECTRUM_DISPLAY_FORM_H -#include "spectrumdisplayform_ui.h" +#include "spectrumdisplayform.ui.h" class SpectrumGUIClass; #include <SpectrumGUIClass.h> @@ -9,10 +9,10 @@ class SpectrumGUIClass; #include <SpectrumGUIClass.h> #include <FrequencyDisplayPlot.h> #include <WaterfallDisplayPlot.h> -#include <Waterfall3DDisplayPlot.h> #include <TimeDomainDisplayPlot.h> #include <ConstellationDisplayPlot.h> #include <QValidator> +#include <QTimer> #include <vector> class SpectrumDisplayForm : public QWidget, public Ui::SpectrumDisplayForm @@ -43,7 +43,6 @@ public slots: void MaxHoldResetBtn_clicked(); void TabChanged(int index); - void PowerLineEdit_textChanged( const QString& valueString ); void SetFrequencyRange( const double newCenterFrequency, const double newStartFrequency, const double newStopFrequency ); @@ -54,15 +53,10 @@ public slots: void waterfallMinimumIntensityChangedCB(double); void WaterfallIntensityColorTypeChanged(int); void WaterfallAutoScaleBtnCB(); - void waterfall3DMaximumIntensityChangedCB(double); - void waterfall3DMinimumIntensityChangedCB(double); - void Waterfall3DIntensityColorTypeChanged(int); - 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); @@ -71,9 +65,11 @@ public slots: double ymin, double ymax); void SetConstellationPenSize(int size); void SetFrequencyAxis(double min, double max); + void SetUpdateTime(double t); private slots: void newFrequencyData( const SpectrumUpdateEvent* ); + void UpdateGuiTimer(); protected: @@ -90,7 +86,6 @@ private: QIntValidator* _intValidator; FrequencyDisplayPlot* _frequencyDisplayPlot; WaterfallDisplayPlot* _waterfallDisplayPlot; - Waterfall3DDisplayPlot* _waterfall3DDisplayPlot; TimeDomainDisplayPlot* _timeDomainDisplayPlot; ConstellationDisplayPlot* _constellationDisplayPlot; SpectrumGUIClass* _system; @@ -111,6 +106,9 @@ private: int d_plot_waterfall3d; int d_plot_time; int d_plot_constellation; + + QTimer *displayTimer; + double d_update_time; }; #endif /* SPECTRUM_DISPLAY_FORM_H */ diff --git a/gr-qtgui/src/lib/spectrumdisplayform.ui b/gr-qtgui/src/lib/spectrumdisplayform.ui index cb7b4f996..5a23bc8a9 100644 --- a/gr-qtgui/src/lib/spectrumdisplayform.ui +++ b/gr-qtgui/src/lib/spectrumdisplayform.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>657</width> + <width>712</width> <height>543</height> </rect> </property> @@ -183,7 +183,7 @@ <property name="minimumSize"> <size> <width>400</width> - <height>332</height> + <height>350</height> </size> </property> <property name="sizeIncrement"> @@ -222,31 +222,6 @@ </property> </widget> </item> - <item row="1" column="3"> - <widget class="QLabel" name="PowerLabel"> - <property name="minimumSize"> - <size> - <width>50</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>50</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>Power</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - <property name="wordWrap"> - <bool>false</bool> - </property> - </widget> - </item> <item row="1" column="1"> <widget class="QPushButton" name="MaxHoldResetBtn"> <property name="sizePolicy"> @@ -266,7 +241,7 @@ </property> </widget> </item> - <item row="1" column="4"> + <item row="1" column="3"> <widget class="QLabel" name="AvgLabel"> <property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> @@ -298,33 +273,8 @@ </property> </widget> </item> - <item row="2" column="4"> - <widget class="QSpinBox" name="AvgLineEdit"/> - </item> <item row="2" column="3"> - <widget class="QLineEdit" name="PowerLineEdit"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>50</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>50</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>1</string> - </property> - </widget> + <widget class="QSpinBox" name="AvgLineEdit"/> </item> <item row="1" column="2"> <spacer name="horizontalSpacer_2"> @@ -517,190 +467,6 @@ </item> </layout> </widget> - <widget class="QWidget" name="Waterfall3DPage"> - <attribute name="title"> - <string>3D Waterfall Display</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_6"> - <item row="0" column="0"> - <widget class="QLabel" name="textLabel1_2"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>100</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>Intensity Display:</string> - </property> - <property name="wordWrap"> - <bool>false</bool> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QComboBox" name="Waterfall3DIntensityComboBox"> - <property name="maximumSize"> - <size> - <width>100</width> - <height>16777215</height> - </size> - </property> - <item> - <property name="text"> - <string>Color</string> - </property> - </item> - <item> - <property name="text"> - <string>White Hot</string> - </property> - </item> - <item> - <property name="text"> - <string>Black Hot</string> - </property> - </item> - <item> - <property name="text"> - <string>Incandescent</string> - </property> - </item> - <item> - <property name="text"> - <string>User Defined</string> - </property> - </item> - </widget> - </item> - <item row="0" column="2"> - <widget class="QwtWheel" name="Waterfall3DMaximumIntensityWheel"> - <property name="minimumSize"> - <size> - <width>200</width> - <height>0</height> - </size> - </property> - <property name="mouseTracking"> - <bool>true</bool> - </property> - <property name="focusPolicy"> - <enum>Qt::WheelFocus</enum> - </property> - <property name="valid"> - <bool>true</bool> - </property> - <property name="totalAngle"> - <double>200.000000000000000</double> - </property> - <property name="viewAngle"> - <double>20.000000000000000</double> - </property> - <property name="mass"> - <double>0.000000000000000</double> - </property> - </widget> - </item> - <item row="0" column="3"> - <widget class="QLabel" name="Waterfall3DMaximumIntensityLabel"> - <property name="maximumSize"> - <size> - <width>100</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>100 dB</string> - </property> - <property name="wordWrap"> - <bool>false</bool> - </property> - </widget> - </item> - <item row="1" column="0" colspan="4"> - <widget class="QFrame" name="Waterfall3DPlotDisplayFrame"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Plain</enum> - </property> - </widget> - </item> - <item row="2" column="0" colspan="2"> - <widget class="QPushButton" name="Waterfall3DAutoScaleBtn"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - <property name="sizeIncrement"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="toolTip"> - <string>Scales the Intensity to the current data extremes.</string> - </property> - <property name="text"> - <string>Auto Scale</string> - </property> - </widget> - </item> - <item row="2" column="2"> - <widget class="QwtWheel" name="Waterfall3DMinimumIntensityWheel"> - <property name="minimumSize"> - <size> - <width>200</width> - <height>0</height> - </size> - </property> - <property name="valid"> - <bool>true</bool> - </property> - <property name="totalAngle"> - <double>200.000000000000000</double> - </property> - <property name="viewAngle"> - <double>20.000000000000000</double> - </property> - <property name="mass"> - <double>0.000000000000000</double> - </property> - </widget> - </item> - <item row="2" column="3"> - <widget class="QLabel" name="Waterfall3DMinimumIntensityLabel"> - <property name="maximumSize"> - <size> - <width>100</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>-100 dB</string> - </property> - <property name="wordWrap"> - <bool>false</bool> - </property> - </widget> - </item> - </layout> - </widget> <widget class="QWidget" name="TimeDomainPage"> <attribute name="title"> <string>Time Domain Display</string> @@ -771,7 +537,6 @@ <include location="global">SpectrumGUIClass.h</include> <include location="global">FrequencyDisplayPlot.h</include> <include location="global">WaterfallDisplayPlot.h</include> - <include location="global">Waterfall3DDisplayPlot.h</include> <include location="global">TimeDomainDisplayPlot.h</include> <include location="global">qvalidator.h</include> <include location="global">vector</include> @@ -844,22 +609,6 @@ </hints> </connection> <connection> - <sender>PowerLineEdit</sender> - <signal>textChanged(QString)</signal> - <receiver>SpectrumDisplayForm</receiver> - <slot>PowerLineEdit_textChanged(QString)</slot> - <hints> - <hint type="sourcelabel"> - <x>482</x> - <y>344</y> - </hint> - <hint type="destinationlabel"> - <x>20</x> - <y>20</y> - </hint> - </hints> - </connection> - <connection> <sender>WindowComboBox</sender> <signal>activated(int)</signal> <receiver>SpectrumDisplayForm</receiver> @@ -924,38 +673,6 @@ </hints> </connection> <connection> - <sender>Waterfall3DMaximumIntensityWheel</sender> - <signal>valueChanged(double)</signal> - <receiver>SpectrumDisplayForm</receiver> - <slot>waterfall3DMaximumIntensityChangedCB(double)</slot> - <hints> - <hint type="sourcelabel"> - <x>217</x> - <y>44</y> - </hint> - <hint type="destinationlabel"> - <x>20</x> - <y>20</y> - </hint> - </hints> - </connection> - <connection> - <sender>Waterfall3DMinimumIntensityWheel</sender> - <signal>valueChanged(double)</signal> - <receiver>SpectrumDisplayForm</receiver> - <slot>waterfall3DMinimumIntensityChangedCB(double)</slot> - <hints> - <hint type="sourcelabel"> - <x>217</x> - <y>349</y> - </hint> - <hint type="destinationlabel"> - <x>20</x> - <y>20</y> - </hint> - </hints> - </connection> - <connection> <sender>FFTSizeComboBox</sender> <signal>activated(QString)</signal> <receiver>SpectrumDisplayForm</receiver> diff --git a/gr-qtgui/src/lib/waterfallGlobalData.cc b/gr-qtgui/src/lib/waterfallGlobalData.cc index 0cbef4ec3..1ba153f0d 100644 --- a/gr-qtgui/src/lib/waterfallGlobalData.cc +++ b/gr-qtgui/src/lib/waterfallGlobalData.cc @@ -3,11 +3,13 @@ #include <waterfallGlobalData.h> -#include <Waterfall3DDisplayPlot.h> - -WaterfallData::WaterfallData(const double minimumFrequency, const double maximumFrequency, const uint64_t fftPoints, const unsigned int historyExtent): - QwtRasterData(QwtDoubleRect(minimumFrequency /* X START */, 0 /* Y START */, maximumFrequency - minimumFrequency /* WIDTH */, static_cast<double>(historyExtent)/* HEIGHT */)) - +WaterfallData::WaterfallData(const double minimumFrequency, + const double maximumFrequency, + const uint64_t fftPoints, + const unsigned int historyExtent) + : QwtRasterData(QwtDoubleRect(minimumFrequency /* X START */, 0 /* Y START */, + maximumFrequency - minimumFrequency /* WIDTH */, + static_cast<double>(historyExtent)/* HEIGHT */)) { _intensityRange = QwtDoubleInterval(-200.0, 0.0); @@ -19,17 +21,20 @@ WaterfallData::WaterfallData(const double minimumFrequency, const double maximum Reset(); } -WaterfallData::~WaterfallData(){ +WaterfallData::~WaterfallData() +{ delete[] _spectrumData; } -void WaterfallData::Reset(){ +void WaterfallData::Reset() +{ memset(_spectrumData, 0x0, _fftPoints*_historyLength*sizeof(double)); _numLinesToUpdate = -1; } -void WaterfallData::Copy(const WaterfallData* rhs){ +void WaterfallData::Copy(const WaterfallData* rhs) +{ if((_fftPoints != rhs->GetNumFFTPoints()) || (boundingRect() != rhs->boundingRect()) ){ _fftPoints = rhs->GetNumFFTPoints(); @@ -43,7 +48,10 @@ void WaterfallData::Copy(const WaterfallData* rhs){ setRange(rhs->range()); } -void WaterfallData::ResizeData(const double startFreq, const double stopFreq, const uint64_t fftPoints){ +void WaterfallData::ResizeData(const double startFreq, + const double stopFreq, + const uint64_t fftPoints) +{ if((fftPoints != GetNumFFTPoints()) || (boundingRect().width() != (stopFreq - startFreq)) || (boundingRect().left() != startFreq)){ @@ -57,21 +65,27 @@ void WaterfallData::ResizeData(const double startFreq, const double stopFreq, co Reset(); } -QwtRasterData *WaterfallData::copy() const{ - WaterfallData* returnData = new WaterfallData(boundingRect().left(), boundingRect().right(), _fftPoints, _historyLength); +QwtRasterData *WaterfallData::copy() const +{ + WaterfallData* returnData = new WaterfallData(boundingRect().left(), + boundingRect().right(), + _fftPoints, _historyLength); returnData->Copy(this); return returnData; } -QwtDoubleInterval WaterfallData::range() const{ +QwtDoubleInterval WaterfallData::range() const +{ return _intensityRange; } -void WaterfallData::setRange(const QwtDoubleInterval& newRange){ +void WaterfallData::setRange(const QwtDoubleInterval& newRange) +{ _intensityRange = newRange; } -double WaterfallData::value(double x, double y) const{ +double WaterfallData::value(double x, double y) const +{ double returnValue = 0.0; const unsigned int intY = static_cast<unsigned int>((1.0 - (y/boundingRect().height())) * @@ -87,11 +101,14 @@ double WaterfallData::value(double x, double y) const{ return returnValue; } -uint64_t WaterfallData::GetNumFFTPoints()const{ +uint64_t WaterfallData::GetNumFFTPoints() const +{ return _fftPoints; } -void WaterfallData::addFFTData(const double* fftData, const uint64_t fftDataSize, const int droppedFrames){ +void WaterfallData::addFFTData(const double* fftData, + const uint64_t fftDataSize, + const int droppedFrames){ if(fftDataSize == _fftPoints){ int64_t heightOffset = _historyLength - 1 - droppedFrames; uint64_t drawingDroppedFrames = droppedFrames; @@ -104,155 +121,44 @@ void WaterfallData::addFFTData(const double* fftData, const uint64_t fftDataSize // Copy the old data over if any available if(heightOffset > 0){ - memmove( _spectrumData, &_spectrumData[(drawingDroppedFrames+1) * _fftPoints], heightOffset * _fftPoints * sizeof(double)) ; + memmove( _spectrumData, &_spectrumData[(drawingDroppedFrames+1) * _fftPoints], + heightOffset * _fftPoints * sizeof(double)) ; } if(drawingDroppedFrames > 0){ // Fill in zeros data for dropped data - memset(&_spectrumData[heightOffset * _fftPoints], 0x00, static_cast<int64_t>(drawingDroppedFrames) * _fftPoints * sizeof(double)); + memset(&_spectrumData[heightOffset * _fftPoints], 0x00, + static_cast<int64_t>(drawingDroppedFrames) * _fftPoints * sizeof(double)); } // add the new buffer memcpy(&_spectrumData[(_historyLength - 1) * _fftPoints], fftData, _fftPoints*sizeof(double)); - } } -double* WaterfallData::GetSpectrumDataBuffer()const{ +double* WaterfallData::GetSpectrumDataBuffer() const +{ return _spectrumData; } -void WaterfallData::SetSpectrumDataBuffer(const double* newData){ +void WaterfallData::SetSpectrumDataBuffer(const double* newData) +{ memcpy(_spectrumData, newData, _fftPoints * _historyLength * sizeof(double)); } -int WaterfallData::GetNumLinesToUpdate()const{ +int WaterfallData::GetNumLinesToUpdate() const +{ return _numLinesToUpdate; } -void WaterfallData::SetNumLinesToUpdate(const int newNum){ +void WaterfallData::SetNumLinesToUpdate(const int newNum) +{ _numLinesToUpdate = newNum; } -void WaterfallData::IncrementNumLinesToUpdate(){ - _numLinesToUpdate++; -} - -Waterfall3DData::Waterfall3DData(const double minimumFrequency, const double maximumFrequency, const uint64_t fftPoints, const unsigned int historyExtent): - WaterfallData(minimumFrequency, maximumFrequency, fftPoints, historyExtent), Qwt3D::Function(){ - - _floorValue = 0.0; - setMinZ(0.0); - setMaxZ(200.0); - - // Create the dummy mesh data until _ResizeMesh is called - data = new double*[1]; - data[0] = new double[1]; - Qwt3D::Function::setMesh(1,1); - - _ResizeMesh(); -} - -Waterfall3DData::~Waterfall3DData(){ - for ( unsigned i = 0; i < umesh_p; i++){ - delete[] data[i]; - } - delete[] data; - -} - -void Waterfall3DData::ResizeData(const double startFreq, const double stopFreq, const uint64_t fftPoints){ - if((fftPoints != GetNumFFTPoints()) || - (boundingRect().width() != (stopFreq - startFreq)) || - (boundingRect().left() != startFreq)){ - WaterfallData::ResizeData(startFreq, stopFreq, fftPoints); - _ResizeMesh(); - } - - Reset(); -} - -bool Waterfall3DData::create() +void WaterfallData::IncrementNumLinesToUpdate() { - if ((umesh_p<=2) || (vmesh_p<=2) || !plotwidget_p) - return false; - - // Almost the same as the old create, except that here we store our own data buffer in the class rather than re-creating it each time... - - unsigned i,j; - - /* get the data */ - double dx = (maxu_p - minu_p) / (umesh_p - 1); - double dy = (maxv_p - minv_p) / (vmesh_p - 1); - - for (i = 0; i < umesh_p; ++i) - { - for (j = 0; j < vmesh_p; ++j) - { - data[i][j] = operator()(minu_p + i*dx, minv_p + j*dy); - - if (data[i][j] > range_p.maxVertex.z) - data[i][j] = range_p.maxVertex.z; - else if (data[i][j] < range_p.minVertex.z) - data[i][j] = range_p.minVertex.z; - } - } - - Q_ASSERT(plotwidget_p); - if (!plotwidget_p) - { - fprintf(stderr,"Function: no valid Plot3D Widget assigned"); - } - else - { - ((Waterfall3DDisplayPlot*)plotwidget_p)->loadFromData(data, umesh_p, vmesh_p, minu_p, maxu_p, minv_p, maxv_p); - } - - return true; -} - -double Waterfall3DData::operator()(double x, double y){ - return value(x,y) - _floorValue; -} - -double Waterfall3DData::GetFloorValue()const{ - return _floorValue; -} - -void Waterfall3DData::SetFloorValue(const double newValue){ - _floorValue = newValue; -} - -double Waterfall3DData::minZ()const{ - return range_p.minVertex.z; -} - -double Waterfall3DData::maxZ()const{ - return range_p.maxVertex.z; -} - -void Waterfall3DData::setMesh(unsigned int, unsigned int){ - // Do Nothing - printf("Should Not Reach this Function\n"); -} - -void Waterfall3DData::_ResizeMesh(){ - // Clear out the old mesh - for ( unsigned i = 0; i < umesh_p; i++){ - delete[] data[i]; - } - delete[] data; - - Qwt3D::Function::setMesh(static_cast<int>(boundingRect().width()/20.0), _historyLength); - setDomain( boundingRect().left(), static_cast<int>(boundingRect().right()), 0, _historyLength); - - /* allocate some space for the mesh */ - unsigned i; - data = new double* [umesh_p] ; - for ( i = 0; i < umesh_p; i++) - { - data[i] = new double [vmesh_p]; - } + _numLinesToUpdate++; } #endif /* WATERFALL_GLOBAL_DATA_CPP */ diff --git a/gr-qtgui/src/lib/waterfallGlobalData.h b/gr-qtgui/src/lib/waterfallGlobalData.h index 6e34ce5b1..51f65064c 100644 --- a/gr-qtgui/src/lib/waterfallGlobalData.h +++ b/gr-qtgui/src/lib/waterfallGlobalData.h @@ -2,9 +2,8 @@ #define WATERFALL_GLOBAL_DATA_HPP #include <qwt_raster_data.h> -#include <qwt3d_function.h> +#include <inttypes.h> -class Waterfall3DDisplayPlot; class WaterfallData: public QwtRasterData { @@ -45,34 +44,4 @@ private: }; -class Waterfall3DData: public WaterfallData, public Qwt3D::Function -{ -public: - Waterfall3DData(const double, const double, const uint64_t, const unsigned int); - virtual ~Waterfall3DData(); - - virtual void ResizeData(const double, const double, const uint64_t); - - virtual bool create(); - virtual void setMesh(unsigned int columns, unsigned int rows); //!< Sets number of rows and columns. - - virtual double operator()(double x, double y); - - virtual double GetFloorValue()const; - virtual void SetFloorValue(const double); - - virtual double minZ()const; - virtual double maxZ()const; - -protected: - void _ResizeMesh(); - - double** data; - double _floorValue; - -private: - -}; - - #endif /* WATERFALL_GLOBAL_DATA_HPP */ |