diff --git a/sdrbase/dsp/spectrumsettings.cpp b/sdrbase/dsp/spectrumsettings.cpp index 3b9b34b8f..d35913079 100644 --- a/sdrbase/dsp/spectrumsettings.cpp +++ b/sdrbase/dsp/spectrumsettings.cpp @@ -53,6 +53,7 @@ void SpectrumSettings::resetToDefaults() m_displayMaxHold = false; m_displayHistogram = false; m_displayGrid = false; + m_truncateFreqScale = false; m_averagingMode = AvgModeNone; m_averagingIndex = 0; m_averagingValue = 1; @@ -130,6 +131,7 @@ QByteArray SpectrumSettings::serialize() const s.writeS32(45, m_measurementPrecision); s.writeS32(46, m_measurementCenterFrequencyOffset); s.writeBool(47, m_findHistogramPeaks); + s.writeBool(58, m_truncateFreqScale); s.writeS32(100, m_histogramMarkers.size()); for (int i = 0; i < m_histogramMarkers.size(); i++) { @@ -242,6 +244,7 @@ bool SpectrumSettings::deserialize(const QByteArray& data) d.readS32(45, &m_measurementPrecision, 1); d.readS32(46, &m_measurementCenterFrequencyOffset, 0); d.readBool(47, &m_findHistogramPeaks, false); + d.readBool(48, &m_truncateFreqScale, false); int histogramMarkersSize; d.readS32(100, &histogramMarkersSize, 0); diff --git a/sdrbase/dsp/spectrumsettings.h b/sdrbase/dsp/spectrumsettings.h index 8d2829fec..04d1fe328 100644 --- a/sdrbase/dsp/spectrumsettings.h +++ b/sdrbase/dsp/spectrumsettings.h @@ -107,6 +107,7 @@ public: bool m_displayCurrent; bool m_displayHistogram; bool m_displayGrid; + bool m_truncateFreqScale; AveragingMode m_averagingMode; int m_averagingIndex; unsigned int m_averagingValue; diff --git a/sdrgui/gui/glspectrum.h b/sdrgui/gui/glspectrum.h index 9b50b5102..0ac19224a 100644 --- a/sdrgui/gui/glspectrum.h +++ b/sdrgui/gui/glspectrum.h @@ -63,6 +63,7 @@ public: void setDisplayGrid(bool display) { m_spectrum->setDisplayGrid(display); } void setDisplayGridIntensity(int intensity) { m_spectrum->setDisplayGridIntensity(intensity); } void setDisplayTraceIntensity(int intensity) { m_spectrum->setDisplayTraceIntensity(intensity); } + void setFreqScaleTruncationMode(bool mode) { m_spectrum->setFreqScaleTruncationMode(mode); } void setLinear(bool linear) { m_spectrum->setLinear(linear); } void setUseCalibration(bool useCalibration) { m_spectrum->setUseCalibration(useCalibration); } void setMeasurementParams(SpectrumSettings::Measurement measurement, diff --git a/sdrgui/gui/glspectrumgui.cpp b/sdrgui/gui/glspectrumgui.cpp index 2ea4ba314..d14ee6923 100644 --- a/sdrgui/gui/glspectrumgui.cpp +++ b/sdrgui/gui/glspectrumgui.cpp @@ -193,6 +193,7 @@ void GLSpectrumGUI::displaySettings() ui->invertWaterfall->setChecked(m_settings.m_invertedWaterfall); ui->grid->setChecked(m_settings.m_displayGrid); ui->gridIntensity->setSliderPosition(m_settings.m_displayGridIntensity); + ui->truncateScale->setChecked(m_settings.m_truncateFreqScale); ui->decay->setToolTip(QString("Decay: %1").arg(m_settings.m_decay)); ui->decayDivisor->setToolTip(QString("Decay divisor: %1").arg(m_settings.m_decayDivisor)); @@ -336,6 +337,7 @@ void GLSpectrumGUI::applySpectrumSettings() m_glSpectrum->setReferenceLevel(refLevel); m_glSpectrum->setPowerRange(powerRange); m_glSpectrum->setFPSPeriodMs(m_settings.m_fpsPeriodMs); + m_glSpectrum->setFreqScaleTruncationMode(m_settings.m_truncateFreqScale); m_glSpectrum->setLinear(m_settings.m_linear); m_glSpectrum->setUseCalibration(m_settings.m_useCalibration); @@ -689,6 +691,13 @@ void GLSpectrumGUI::on_gridIntensity_valueChanged(int index) applySettings(); } +void GLSpectrumGUI::on_truncateScale_toggled(bool checked) +{ + m_settings.m_truncateFreqScale = checked; + qDebug("GLSpectrumGUI::on_truncateScale_toggled: m_truncateFreqScale: %s", (m_settings.m_truncateFreqScale ? "on" : "off")); + applySettings(); +} + void GLSpectrumGUI::on_traceIntensity_valueChanged(int index) { m_settings.m_displayTraceIntensity = index; diff --git a/sdrgui/gui/glspectrumgui.h b/sdrgui/gui/glspectrumgui.h index 6612100cf..3d3f47c8e 100644 --- a/sdrgui/gui/glspectrumgui.h +++ b/sdrgui/gui/glspectrumgui.h @@ -103,6 +103,7 @@ private slots: void on_spectrogramStyle_currentIndexChanged(int index); void on_colorMap_currentIndexChanged(int index); void on_gridIntensity_valueChanged(int index); + void on_truncateScale_toggled(bool checked); void on_traceIntensity_valueChanged(int index); void on_averagingMode_currentIndexChanged(int index); void on_averaging_currentIndexChanged(int index); diff --git a/sdrgui/gui/glspectrumgui.ui b/sdrgui/gui/glspectrumgui.ui index edc077739..cc9ef8907 100644 --- a/sdrgui/gui/glspectrumgui.ui +++ b/sdrgui/gui/glspectrumgui.ui @@ -88,6 +88,29 @@ + + + + Truncate non significant upper digits from frequency scale + + + Grid + + + + :/truncate.png:/truncate.png + + + + 16 + 16 + + + + true + + + diff --git a/sdrgui/gui/glspectrumview.cpp b/sdrgui/gui/glspectrumview.cpp index a6bdf7183..f830ec9fd 100644 --- a/sdrgui/gui/glspectrumview.cpp +++ b/sdrgui/gui/glspectrumview.cpp @@ -492,6 +492,12 @@ void GLSpectrumView::setDisplayTraceIntensity(int intensity) update(); } +void GLSpectrumView::setFreqScaleTruncationMode(bool mode) +{ + m_frequencyScale.setTruncateMode(mode); + update(); +} + void GLSpectrumView::setLinear(bool linear) { m_mutex.lock(); diff --git a/sdrgui/gui/glspectrumview.h b/sdrgui/gui/glspectrumview.h index 234b220bc..b14c4fa93 100644 --- a/sdrgui/gui/glspectrumview.h +++ b/sdrgui/gui/glspectrumview.h @@ -179,6 +179,7 @@ public: void setDisplayGrid(bool display); void setDisplayGridIntensity(int intensity); void setDisplayTraceIntensity(int intensity); + void setFreqScaleTruncationMode(bool mode); void setLinear(bool linear); void setUseCalibration(bool useCalibration); void setMeasurements(SpectrumMeasurements *measurements) { m_measurements = measurements; } diff --git a/sdrgui/gui/scaleengine.cpp b/sdrgui/gui/scaleengine.cpp index c096a16f7..2bd490b45 100644 --- a/sdrgui/gui/scaleengine.cpp +++ b/sdrgui/gui/scaleengine.cpp @@ -30,12 +30,18 @@ static double trunc(double d) QString ScaleEngine::formatTick(double value, int decimalPlaces) { + if (m_truncated && (m_physicalUnit != Unit::Scientific)) + { + value = ((value * m_scale) - m_truncationValue) / m_scale; + qDebug("ScaleEngine::formatTick: value: %f decimalPlaces: %d m_scale: %f", value, decimalPlaces, m_scale); + } + if (m_physicalUnit != Unit::TimeHMS) { if (m_physicalUnit == Unit::Scientific) { return QString("%1").arg(m_makeOpposite ? -value : value, 0, 'e', m_fixedDecimalPlaces); } else { - return QString("%1").arg(m_makeOpposite ? -value : value, 0, 'f', decimalPlaces); + return QString("%1%2").arg(m_truncated ? "'" : "").arg(m_makeOpposite ? -value : value, 0, 'f', decimalPlaces); } } else @@ -49,28 +55,41 @@ QString ScaleEngine::formatTick(double value, int decimalPlaces) double orig = fabs(actual); double tmp; - if(orig >= 86400.0) { + if (m_truncated) { + str = "'"; + } + + if (orig >= 86400.0) + { tmp = floor(actual / 86400.0); - str = QString("%1.").arg(tmp, 0, 'f', 0); + str += QString("%1.").arg(tmp, 0, 'f', 0); actual -= tmp * 86400.0; - if(actual < 0.0) + + if (actual < 0.0) { actual *= -1.0; + } } - if(orig >= 3600.0) { + if (orig >= 3600.0) + { tmp = floor(actual / 3600.0); str += QString("%1:").arg(tmp, 2, 'f', 0, QChar('0')); actual -= tmp * 3600.0; - if(actual < 0.0) + + if (actual < 0.0) { actual *= -1.0; + } } - if(orig >= 60.0) { + if (orig >= 60.0) + { tmp = floor(actual / 60.0); str += QString("%1:").arg(tmp, 2, 'f', 0, QChar('0')); actual -= tmp * 60.0; - if(actual < 0.0) + + if (actual < 0.0) { actual *= -1.0; + } } tmp = m_makeOpposite ? -actual : actual; @@ -104,8 +123,11 @@ void ScaleEngine::calcScaleFactor() { double median, range, freqBase; - median = ((m_rangeMax - m_rangeMin) / 2.0) + m_rangeMin; - range = (m_rangeMax - m_rangeMin); + double rangeMin = m_rangeMin; + double rangeMax = m_rangeMax; + + median = ((rangeMax - rangeMin) / 2.0) + rangeMin; + range = (rangeMax - rangeMin); freqBase = (median == 0 ? range : median); m_scale = 1.0; @@ -361,8 +383,10 @@ void ScaleEngine::reCalc() float lastEndPos; bool done; - if(!m_recalc) + if (!m_recalc) { return; + } + m_recalc = false; m_tickList.clear(); @@ -391,6 +415,8 @@ void ScaleEngine::reCalc() numMajorTicks = (int)((rangeMaxScaled - rangeMinScaled) / m_majorTickValueDistance); + updateTruncation(numMajorTicks); + if(numMajorTicks == 0) { forceTwoTicks(); return; @@ -518,13 +544,16 @@ ScaleEngine::ScaleEngine() : m_rangeMin(-1.0), m_rangeMax(1.0), m_recalc(true), - m_scale(1.0f), + m_scale(1.0), m_majorTickValueDistance(1.0), m_firstMajorTickValue(1.0), m_numMinorTicks(1), m_decimalPlaces(1), m_fixedDecimalPlaces(2), - m_makeOpposite(false) + m_makeOpposite(false), + m_truncateMode(false), + m_truncated(false), + m_truncationValue(0.0) { } @@ -570,7 +599,8 @@ void ScaleEngine::setRange(Unit::Physical physicalUnit, float rangeMin, float ra tmpRangeMin = rangeMin; tmpRangeMax = rangeMax; - if((tmpRangeMin != m_rangeMin) || (tmpRangeMax != m_rangeMax) || (m_physicalUnit != physicalUnit)) { + if ((tmpRangeMin != m_rangeMin) || (tmpRangeMax != m_rangeMax) || (m_physicalUnit != physicalUnit)) + { m_physicalUnit = physicalUnit; m_rangeMin = tmpRangeMin; m_rangeMax = tmpRangeMax; @@ -623,3 +653,48 @@ float ScaleEngine::getScaleWidth() } return max; } + +void ScaleEngine::setTruncateMode(bool mode) +{ + qDebug("ScaleEngine::setTruncateMode: %s", (mode ? "on" : "off")); + m_truncateMode = mode; + m_recalc = true; + reCalc(); +} + +void ScaleEngine::updateTruncation(int numMajorTicks) +{ + m_truncated = false; + m_truncationValue = 0.0; + + if (!m_truncateMode) { + return; + } + + if (order(m_rangeMax) != order(m_rangeMin)) { + return; + } + + double width = m_rangeMax - m_rangeMin; + int widthOrder = order(width); + int maxOrder = order(m_rangeMax); + + if ((widthOrder < 0) || (maxOrder < 0) || (widthOrder == maxOrder)) { + return; + } + + for (int i = widthOrder+1; i <= maxOrder; i++) + { + int irangeMin = floor(m_rangeMin / pow(10, i)); + int irangeMax = floor(m_rangeMin / pow(10, i)); + + if (irangeMin == irangeMax) + { + m_truncated = true; + m_truncationValue = irangeMin * pow(10, i); + break; + } + } + + qDebug("ScaleEngine::updateTruncation: m_truncationValue: %f", m_truncationValue); +} diff --git a/sdrgui/gui/scaleengine.h b/sdrgui/gui/scaleengine.h index 904b561fe..b562004e8 100644 --- a/sdrgui/gui/scaleengine.h +++ b/sdrgui/gui/scaleengine.h @@ -19,6 +19,8 @@ #ifndef INCLUDE_SCALEENGINE_H #define INCLUDE_SCALEENGINE_H +#include + #include #include #include @@ -48,6 +50,7 @@ public: float getRangeMax() const { return m_rangeMax; } void setMakeOpposite(bool makeOpposite) { m_makeOpposite = makeOpposite; } void setFixedDecimalPlaces(int decimalPlaces) { m_fixedDecimalPlaces =decimalPlaces; } + void setTruncateMode(bool mode); float getPosFromValue(double value); float getValueFromPos(double pos); @@ -65,10 +68,10 @@ private: float m_charSize; // graph configuration - float m_size; + double m_size; Unit::Physical m_physicalUnit; - float m_rangeMin; - float m_rangeMax; + double m_rangeMin; + double m_rangeMax; // calculated values bool m_recalc; @@ -81,6 +84,9 @@ private: int m_decimalPlaces; int m_fixedDecimalPlaces; bool m_makeOpposite; // will show -value instead of value + bool m_truncateMode; //!< truncate upper digits mode + bool m_truncated; //!< true if upper digits are truncated + double m_truncationValue; //!< value to subreact from tick display values QString formatTick(double value, int decimalPlaces); void calcCharSize(); @@ -89,6 +95,11 @@ private: int calcTickTextSize(double distance); void forceTwoTicks(); void reCalc(); + void updateTruncation(int numMajorTicks); + + inline int order(double value) { + return floor(log10(value)); + } double majorTickValue(int tick); double minorTickValue(int tick); diff --git a/sdrgui/resources/res.qrc b/sdrgui/resources/res.qrc index 9817bd60e..1c7d14c12 100644 --- a/sdrgui/resources/res.qrc +++ b/sdrgui/resources/res.qrc @@ -1,5 +1,6 @@ + truncate.png caliper.png flip_windows.png waterfall_3d.png diff --git a/sdrgui/resources/truncate.png b/sdrgui/resources/truncate.png new file mode 100644 index 000000000..87251a2a0 Binary files /dev/null and b/sdrgui/resources/truncate.png differ diff --git a/sdrgui/resources/truncate.xcf b/sdrgui/resources/truncate.xcf new file mode 100644 index 000000000..a9f83e8aa Binary files /dev/null and b/sdrgui/resources/truncate.xcf differ