diff options
Diffstat (limited to 'gr-qtgui/src/lib/WaterfallDisplayPlot.cc')
-rw-r--r-- | gr-qtgui/src/lib/WaterfallDisplayPlot.cc | 547 |
1 files changed, 0 insertions, 547 deletions
diff --git a/gr-qtgui/src/lib/WaterfallDisplayPlot.cc b/gr-qtgui/src/lib/WaterfallDisplayPlot.cc deleted file mode 100644 index a8e5361e7..000000000 --- a/gr-qtgui/src/lib/WaterfallDisplayPlot.cc +++ /dev/null @@ -1,547 +0,0 @@ -#ifndef WATERFALL_DISPLAY_PLOT_C -#define WATERFALL_DISPLAY_PLOT_C - -#include <WaterfallDisplayPlot.h> - -#include <qwt_color_map.h> -#include <qwt_scale_widget.h> -#include <qwt_scale_draw.h> -#include <qwt_plot_zoomer.h> -#include <qwt_plot_panner.h> -#include <qwt_plot_layout.h> - -#include <qapplication.h> - -#include <boost/date_time/posix_time/posix_time.hpp> -namespace pt = boost::posix_time; - -class FreqOffsetAndPrecisionClass -{ -public: - FreqOffsetAndPrecisionClass(const int freqPrecision) - { - _frequencyPrecision = freqPrecision; - _centerFrequency = 0; - } - - virtual ~FreqOffsetAndPrecisionClass() - { - } - - virtual unsigned int GetFrequencyPrecision() const - { - return _frequencyPrecision; - } - - virtual void SetFrequencyPrecision(const unsigned int newPrecision) - { - _frequencyPrecision = newPrecision; - } - - virtual double GetCenterFrequency() const - { - return _centerFrequency; - } - - virtual void SetCenterFrequency(const double newFreq) - { - _centerFrequency = newFreq; - } - -protected: - unsigned int _frequencyPrecision; - double _centerFrequency; - -private: - -}; - -class WaterfallFreqDisplayScaleDraw: public QwtScaleDraw, public FreqOffsetAndPrecisionClass{ -public: - WaterfallFreqDisplayScaleDraw(const unsigned int precision) - : QwtScaleDraw(), FreqOffsetAndPrecisionClass(precision) - { - } - - virtual ~WaterfallFreqDisplayScaleDraw() - { - } - - QwtText label(double value) const - { - return QString("%1").arg(value, 0, 'f', GetFrequencyPrecision()); - } - - virtual void initiateUpdate() - { - invalidateCache(); - } - -protected: - -private: - -}; - -class TimeScaleData -{ -public: - TimeScaleData() - { - timespec_reset(&_zeroTime); - _secondsPerLine = 1.0; - } - - virtual ~TimeScaleData() - { - } - - virtual timespec GetZeroTime() const - { - return _zeroTime; - } - - virtual void SetZeroTime(const timespec newTime) - { - _zeroTime = newTime; - } - - virtual void SetSecondsPerLine(const double newTime) - { - _secondsPerLine = newTime; - } - - virtual double GetSecondsPerLine() const - { - return _secondsPerLine; - } - - -protected: - timespec _zeroTime; - double _secondsPerLine; - -private: - -}; - -class QwtTimeScaleDraw: public QwtScaleDraw, public TimeScaleData -{ -public: - QwtTimeScaleDraw():QwtScaleDraw(),TimeScaleData() - { - } - - virtual ~QwtTimeScaleDraw() - { - } - - virtual QwtText label(double value) const - { - timespec lineTime = timespec_add(GetZeroTime(), (-value) * GetSecondsPerLine()); - std::string time_str = pt::to_simple_string(pt::from_time_t(lineTime.tv_sec)); - - // lops off the YYYY-mmm-DD part of the string - int ind = time_str.find(" "); - if(ind != std::string::npos) - time_str = time_str.substr(ind); - return QwtText(QString("").sprintf("%s.%03ld", time_str.c_str(), lineTime.tv_nsec/1000000)); - } - - virtual void initiateUpdate() - { - // Do this in one call rather than when zeroTime and secondsPerLine - // updates is to prevent the display from being updated too often... - invalidateCache(); - } - -protected: - -private: - -}; - -class WaterfallZoomer: public QwtPlotZoomer, public TimeScaleData, - public FreqOffsetAndPrecisionClass -{ -public: - WaterfallZoomer(QwtPlotCanvas* canvas, const unsigned int freqPrecision) - : QwtPlotZoomer(canvas), TimeScaleData(), - FreqOffsetAndPrecisionClass(freqPrecision) - { - setTrackerMode(QwtPicker::AlwaysOn); - } - - virtual ~WaterfallZoomer() - { - } - - virtual void updateTrackerText() - { - updateDisplay(); - } - - void SetUnitType(const std::string &type) - { - _unitType = type; - } - -protected: - using QwtPlotZoomer::trackerText; - virtual QwtText trackerText( const QwtDoublePoint& p ) const - { - timespec lineTime = timespec_add(GetZeroTime(), (-p.y()) * GetSecondsPerLine()); - std::string time_str = pt::to_simple_string(pt::from_time_t(lineTime.tv_sec)); - - // lops off the YYYY-mmm-DD part of the string - int ind = time_str.find(" "); - if(ind != std::string::npos) - time_str = time_str.substr(ind); - QString yLabel(QString("").sprintf("%s.%03ld", time_str.c_str(), lineTime.tv_nsec/1000000)); - - QwtText t(QString("%1 %2, %3"). - arg(p.x(), 0, 'f', GetFrequencyPrecision()). - arg(_unitType.c_str()).arg(yLabel)); - return t; - } - -private: - std::string _unitType; -}; - - -WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent) - : QwtPlot(parent) -{ - _zoomer = NULL; - _startFrequency = 0; - _stopFrequency = 4000; - - resize(parent->width(), parent->height()); - _numPoints = 1024; - - _waterfallData = new WaterfallData(_startFrequency, _stopFrequency, _numPoints, 200); - - QPalette palette; - palette.setColor(canvas()->backgroundRole(), QColor("white")); - canvas()->setPalette(palette); - - setAxisTitle(QwtPlot::xBottom, "Frequency (Hz)"); - setAxisScaleDraw(QwtPlot::xBottom, new WaterfallFreqDisplayScaleDraw(0)); - - setAxisTitle(QwtPlot::yLeft, "Time"); - setAxisScaleDraw(QwtPlot::yLeft, new QwtTimeScaleDraw()); - - timespec_reset(&_lastReplot); - - d_spectrogram = new PlotWaterfall(_waterfallData, "Waterfall Display"); - - _intensityColorMapType = INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR; - - QwtLinearColorMap colorMap(Qt::darkCyan, Qt::white); - colorMap.addColorStop(0.25, Qt::cyan); - colorMap.addColorStop(0.5, Qt::yellow); - colorMap.addColorStop(0.75, Qt::red); - - d_spectrogram->setColorMap(colorMap); - - d_spectrogram->attach(this); - - // LeftButton for the zooming - // MidButton for the panning - // RightButton: zoom out by 1 - // Ctrl+RighButton: zoom out to full size - - _zoomer = new WaterfallZoomer(canvas(), 0); -#if QT_VERSION < 0x040000 - _zoomer->setMousePattern(QwtEventPattern::MouseSelect2, - Qt::RightButton, Qt::ControlModifier); -#else - _zoomer->setMousePattern(QwtEventPattern::MouseSelect2, - Qt::RightButton, Qt::ControlModifier); -#endif - _zoomer->setMousePattern(QwtEventPattern::MouseSelect3, - Qt::RightButton); - - _panner = new QwtPlotPanner(canvas()); - _panner->setAxisEnabled(QwtPlot::yRight, false); - _panner->setMouseButton(Qt::MidButton); - - // Avoid jumping when labels with more/less digits - // appear/disappear when scrolling vertically - - const QFontMetrics fm(axisWidget(QwtPlot::yLeft)->font()); - QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft); - sd->setMinimumExtent( fm.width("100.00") ); - - const QColor c(Qt::white); - _zoomer->setRubberBandPen(c); - _zoomer->setTrackerPen(c); - - _UpdateIntensityRangeDisplay(); -} - -WaterfallDisplayPlot::~WaterfallDisplayPlot() -{ - delete _waterfallData; - delete d_spectrogram; -} - -void -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); - newSize.setWidth(_stopFrequency-_startFrequency); - _zoomer->zoom(newSize); - _zoomer->setZoomBase(newSize); - _zoomer->zoom(0); -} - -void -WaterfallDisplayPlot::SetFrequencyRange(const double constStartFreq, - const double constStopFreq, - const double constCenterFreq, - const bool useCenterFrequencyFlag, - const double units, const std::string &strunits) -{ - double startFreq = constStartFreq / units; - double stopFreq = constStopFreq / units; - double centerFreq = constCenterFreq / units; - - _useCenterFrequencyFlag = useCenterFrequencyFlag; - - if(_useCenterFrequencyFlag){ - startFreq = (startFreq + centerFreq); - stopFreq = (stopFreq + centerFreq); - } - - 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 WaterfallFreqDisplayScaleDraw(display_units)); - setAxisTitle(QwtPlot::xBottom, QString("Frequency (%1)").arg(strunits.c_str())); - - if(reset) { - Reset(); - } - - ((WaterfallZoomer*)_zoomer)->SetFrequencyPrecision(display_units); - ((WaterfallZoomer*)_zoomer)->SetUnitType(strunits); - } - } -} - - -double -WaterfallDisplayPlot::GetStartFrequency() const -{ - return _startFrequency; -} - -double -WaterfallDisplayPlot::GetStopFrequency() const -{ - return _stopFrequency; -} - -void -WaterfallDisplayPlot::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(); - - d_spectrogram->invalidateCache(); - d_spectrogram->itemChanged(); - - if(isVisible()){ - replot(); - } - - _lastReplot = get_highres_clock(); - } - - 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(); - } - } -} - -void -WaterfallDisplayPlot::SetIntensityRange(const double minIntensity, - const double maxIntensity) -{ - _waterfallData->setRange(QwtDoubleInterval(minIntensity, maxIntensity)); - - emit UpdatedLowerIntensityLevel(minIntensity); - emit UpdatedUpperIntensityLevel(maxIntensity); - - _UpdateIntensityRangeDisplay(); -} - -void -WaterfallDisplayPlot::replot() -{ - QwtTimeScaleDraw* timeScale = (QwtTimeScaleDraw*)axisScaleDraw(QwtPlot::yLeft); - timeScale->initiateUpdate(); - - WaterfallFreqDisplayScaleDraw* freqScale = (WaterfallFreqDisplayScaleDraw*)axisScaleDraw(QwtPlot::xBottom); - freqScale->initiateUpdate(); - - // Update the time axis display - if(axisWidget(QwtPlot::yLeft) != NULL){ - axisWidget(QwtPlot::yLeft)->update(); - } - - // Update the Frequency Offset Display - if(axisWidget(QwtPlot::xBottom) != NULL){ - axisWidget(QwtPlot::xBottom)->update(); - } - - if(_zoomer != NULL){ - ((WaterfallZoomer*)_zoomer)->updateTrackerText(); - } - - QwtPlot::replot(); -} - -void -WaterfallDisplayPlot::resizeSlot( QSize *s ) -{ - resize(s->width(), s->height()); -} - -int -WaterfallDisplayPlot::GetIntensityColorMapType() const -{ - return _intensityColorMapType; -} - -void -WaterfallDisplayPlot::SetIntensityColorMapType(const int newType, - const QColor lowColor, - const QColor highColor) -{ - if((_intensityColorMapType != newType) || - ((newType == INTENSITY_COLOR_MAP_TYPE_USER_DEFINED) && - (lowColor.isValid() && highColor.isValid()))){ - switch(newType){ - case INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR:{ - _intensityColorMapType = newType; - QwtLinearColorMap colorMap(Qt::darkCyan, Qt::white); - colorMap.addColorStop(0.25, Qt::cyan); - colorMap.addColorStop(0.5, Qt::yellow); - colorMap.addColorStop(0.75, Qt::red); - d_spectrogram->setColorMap(colorMap); - break; - } - case INTENSITY_COLOR_MAP_TYPE_WHITE_HOT:{ - _intensityColorMapType = newType; - QwtLinearColorMap colorMap(Qt::black, Qt::white); - d_spectrogram->setColorMap(colorMap); - break; - } - case INTENSITY_COLOR_MAP_TYPE_BLACK_HOT:{ - _intensityColorMapType = newType; - QwtLinearColorMap colorMap(Qt::white, Qt::black); - d_spectrogram->setColorMap(colorMap); - break; - } - case INTENSITY_COLOR_MAP_TYPE_INCANDESCENT:{ - _intensityColorMapType = newType; - QwtLinearColorMap colorMap(Qt::black, Qt::white); - colorMap.addColorStop(0.5, Qt::darkRed); - d_spectrogram->setColorMap(colorMap); - break; - } - case INTENSITY_COLOR_MAP_TYPE_USER_DEFINED:{ - _userDefinedLowIntensityColor = lowColor; - _userDefinedHighIntensityColor = highColor; - _intensityColorMapType = newType; - QwtLinearColorMap colorMap(_userDefinedLowIntensityColor, _userDefinedHighIntensityColor); - d_spectrogram->setColorMap(colorMap); - break; - } - default: break; - } - - _UpdateIntensityRangeDisplay(); - } -} - -const QColor -WaterfallDisplayPlot::GetUserDefinedLowIntensityColor() const -{ - return _userDefinedLowIntensityColor; -} - -const QColor -WaterfallDisplayPlot::GetUserDefinedHighIntensityColor() const -{ - return _userDefinedHighIntensityColor; -} - -void -WaterfallDisplayPlot::_UpdateIntensityRangeDisplay() -{ - QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight); - rightAxis->setTitle("Intensity (dB)"); - rightAxis->setColorBarEnabled(true); - rightAxis->setColorMap(d_spectrogram->data()->range(), - d_spectrogram->colorMap()); - - setAxisScale(QwtPlot::yRight, - d_spectrogram->data()->range().minValue(), - d_spectrogram->data()->range().maxValue() ); - enableAxis(QwtPlot::yRight); - - plotLayout()->setAlignCanvasToScales(true); - - // Tell the display to redraw everything - d_spectrogram->invalidateCache(); - d_spectrogram->itemChanged(); - - // Draw again - replot(); - - // Update the last replot timer - _lastReplot = get_highres_clock(); -} - -#endif /* WATERFALL_DISPLAY_PLOT_C */ |