class FreqPrecisionClass
{
public:
- FreqPrecisionClass(const int freqPrecision){
+ FreqPrecisionClass(const int freqPrecision)
+ {
_frequencyPrecision = freqPrecision;
}
- virtual ~FreqPrecisionClass(){
+ virtual ~FreqPrecisionClass()
+ {
}
- virtual unsigned int GetFrequencyPrecision()const{
+ virtual unsigned int GetFrequencyPrecision() const
+ {
return _frequencyPrecision;
}
- virtual void SetFrequencyPrecision(const unsigned int newPrecision){
+ virtual void SetFrequencyPrecision(const unsigned int newPrecision)
+ {
_frequencyPrecision = newPrecision;
}
protected:
};
-class FreqDisplayScaleDraw: public QwtScaleDraw, public FreqPrecisionClass{
+class FreqDisplayScaleDraw: public QwtScaleDraw, public FreqPrecisionClass
+{
public:
- FreqDisplayScaleDraw(const unsigned int precision):QwtScaleDraw(), FreqPrecisionClass(precision){
-
+ FreqDisplayScaleDraw(const unsigned int precision)
+ : QwtScaleDraw(), FreqPrecisionClass(precision)
+ {
}
- virtual ~FreqDisplayScaleDraw(){
-
+ virtual ~FreqDisplayScaleDraw()
+ {
}
- virtual QwtText label(double value)const{
+ virtual QwtText label(double value) const
+ {
return QString("%1").arg(value, 0, 'f', GetFrequencyPrecision());
}
class FreqDisplayZoomer: public QwtPlotZoomer, public FreqPrecisionClass
{
public:
- FreqDisplayZoomer(QwtPlotCanvas* canvas, const unsigned int freqPrecision):QwtPlotZoomer(canvas),FreqPrecisionClass(freqPrecision)
+ FreqDisplayZoomer(QwtPlotCanvas* canvas, const unsigned int freqPrecision)
+ : QwtPlotZoomer(canvas),FreqPrecisionClass(freqPrecision)
{
setTrackerMode(QwtPicker::AlwaysOn);
}
updateDisplay();
}
-protected:
- virtual QwtText trackerText( const QwtDoublePoint& p ) const
+ void SetUnitType(const std::string &type)
{
- QwtText t(QString("%1 %2, %3 dB").arg(p.x(), 0, 'f', GetFrequencyPrecision()).arg( (GetFrequencyPrecision() == 0) ? "Hz" : "kHz").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):QwtPlot(parent){
+FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent)
+ : QwtPlot(parent)
+{
_startFrequency = 0;
_stopFrequency = 4000;
timespec_reset(&_lastReplot);
resize(parent->width(), parent->height());
-
- _displayIntervalTime = (1.0/10.0); // 1/10 of a second between updates
-
+
_useCenterFrequencyFlag = false;
_numPoints = 1024;
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;
setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
- setAxisScale(QwtPlot::yLeft, -210, 5);
+ setAxisScale(QwtPlot::yLeft, _minYAxis, _maxYAxis);
setAxisTitle(QwtPlot::yLeft, "Power (dB)");
// Automatically deleted when parent is deleted
_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));
_maxFFTPoints[number] = -280.0;
}
- _resetXAxisPoints();
-
-
// set up peak marker
QwtSymbol symbol;
_zoomer->setRubberBandPen(c);
_zoomer->setTrackerPen(c);
+ // Do this after the zoomer has been built
+ _resetXAxisPoints();
}
-FrequencyDisplayPlot::~FrequencyDisplayPlot(){
+FrequencyDisplayPlot::~FrequencyDisplayPlot()
+{
delete[] _dataPoints;
delete[] _maxFFTPoints;
delete[] _minFFTPoints;
// _zoomer and _panner deleted when parent deleted
}
-void FrequencyDisplayPlot::SetFrequencyRange(const double constStartFreq, const double constStopFreq, const double centerFrequency, const bool useCenterFrequencyFlag){
- double startFreq = constStartFreq;
- double stopFreq = constStopFreq;
+void
+FrequencyDisplayPlot::set_yaxis(double min, double max)
+{
+ // Get the new max/min values for the plot
+ _minYAxis = min;
+ _maxYAxis = max;
+
+ // Set the axis max/min to the new values
+ setAxisScale(QwtPlot::yLeft, _minYAxis, _maxYAxis);
+
+ // Reset the base zoom level to the new axis scale set here
+ _zoomer->setZoomBase();
+}
+
+void
+FrequencyDisplayPlot::SetFrequencyRange(const double constStartFreq,
+ const double constStopFreq,
+ const double constCenterFreq,
+ const bool useCenterFrequencyFlag,
+ const double units, const std::string &strunits)
+{
+ double startFreq = constStartFreq / units;
+ double stopFreq = constStopFreq / units;
+ double centerFreq = constCenterFreq / units;
_useCenterFrequencyFlag = useCenterFrequencyFlag;
if(_useCenterFrequencyFlag){
- startFreq = (startFreq + centerFrequency) / 1000.0;
- stopFreq = (stopFreq + centerFrequency) / 1000.0;
+ startFreq = (startFreq + centerFreq);
+ stopFreq = (stopFreq + centerFreq);
}
- if((stopFreq > 0) && (stopFreq > startFreq)){
+ bool reset = false;
+ if((startFreq != _startFrequency) || (stopFreq != _stopFrequency))
+ reset = true;
+
+ if(stopFreq > startFreq) {
_startFrequency = startFreq;
_stopFrequency = stopFreq;
- _resetXAxisPoints();
-
- // Load up the new base zoom settings
- QwtDoubleRect newSize = _zoomer->zoomBase();
- newSize.setLeft(_startFrequency);
- newSize.setWidth(_stopFrequency-_startFrequency);
- _zoomer->setZoomBase(newSize);
-
- // Zooms back to the base and clears any other zoom levels
- _zoomer->zoom(0);
-
- setAxisScale(QwtPlot::xBottom, _startFrequency, _stopFrequency);
- }
-
- if(useCenterFrequencyFlag){
- setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(3));
- setAxisTitle(QwtPlot::xBottom, "RF Frequency (kHz)");
- ((FreqDisplayZoomer*)_zoomer)->SetFrequencyPrecision(3);
- }
- else{
- setAxisScaleDraw(QwtPlot::xBottom, new FreqDisplayScaleDraw(0));
- setAxisTitle(QwtPlot::xBottom, "Frequency (Hz)");
- ((FreqDisplayZoomer*)_zoomer)->SetFrequencyPrecision(0);
+
+ 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);
+ }
}
-
- // Load up the new base zoom settings
- QwtDoubleRect newSize = _zoomer->zoomBase();
- newSize.setLeft(_startFrequency);
- newSize.setWidth(_stopFrequency-_startFrequency);
- _zoomer->setZoomBase(newSize);
-
- // Zooms back to the base and clears any other zoom levels
- _zoomer->zoom(0);
}
-double FrequencyDisplayPlot::GetStartFrequency()const{
+double
+FrequencyDisplayPlot::GetStartFrequency() const
+{
return _startFrequency;
}
-double FrequencyDisplayPlot::GetStopFrequency()const{
+double
+FrequencyDisplayPlot::GetStopFrequency() const
+{
return _stopFrequency;
}
-void FrequencyDisplayPlot::replot(){
-
- const timespec startTime = get_highres_clock();
-
+void
+FrequencyDisplayPlot::replot()
+{
_markerNoiseFloorAmplitude->setYValue(_noiseFloorAmplitude);
// Make sure to take into account the start frequency
_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
+FrequencyDisplayPlot::resizeSlot( QSize *s )
+{
+ resize(s->width(), s->height());
}
-void FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDataPoints, const double noiseFloorAmplitude, const double peakFrequency, const double peakAmplitude){
- if(numDataPoints > 0){
-
- if(numDataPoints != _numPoints){
+void
+FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDataPoints,
+ const double noiseFloorAmplitude, const double peakFrequency,
+ const double peakAmplitude, const double timeInterval)
+{
+ // 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;
_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]){
_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();
}
}
-void FrequencyDisplayPlot::ClearMaxData(){
+void
+FrequencyDisplayPlot::ClearMaxData()
+{
for(int64_t number = 0; number < _numPoints; number++){
- _maxFFTPoints[number] = -280.0;
+ _maxFFTPoints[number] = _minYAxis;
}
}
-void FrequencyDisplayPlot::ClearMinData(){
+void
+FrequencyDisplayPlot::ClearMinData()
+{
for(int64_t number = 0; number < _numPoints; number++){
- _minFFTPoints[number] = 200.0;
+ _minFFTPoints[number] = _maxYAxis;
}
}
-void FrequencyDisplayPlot::SetMaxFFTVisible(const bool visibleFlag){
+void
+FrequencyDisplayPlot::SetMaxFFTVisible(const bool visibleFlag)
+{
_max_fft_plot_curve->setVisible(visibleFlag);
}
-void FrequencyDisplayPlot::SetMinFFTVisible(const bool visibleFlag){
+void
+FrequencyDisplayPlot::SetMinFFTVisible(const bool visibleFlag)
+{
_min_fft_plot_curve->setVisible(visibleFlag);
}
-void FrequencyDisplayPlot::_resetXAxisPoints(){
+void
+FrequencyDisplayPlot::_resetXAxisPoints()
+{
double fft_bin_size = (_stopFrequency-_startFrequency) / static_cast<double>(_numPoints);
double freqValue = _startFrequency;
for(int64_t loc = 0; loc < _numPoints; loc++){
_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 FrequencyDisplayPlot::SetLowerIntensityLevel(const double lowerIntensityLevel){
+void
+FrequencyDisplayPlot::SetLowerIntensityLevel(const double lowerIntensityLevel)
+{
_lower_intensity_marker->setYValue( lowerIntensityLevel );
}
-void FrequencyDisplayPlot::SetUpperIntensityLevel(const double upperIntensityLevel){
+void
+FrequencyDisplayPlot::SetUpperIntensityLevel(const double upperIntensityLevel)
+{
_upper_intensity_marker->setYValue( upperIntensityLevel );
}