mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 09:18:54 -05:00
Spectrum frequency ticks MSB truncation: base algorithm
This commit is contained in:
parent
c63834297a
commit
45ef7c5be0
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -88,6 +88,29 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="truncateScale">
|
||||
<property name="toolTip">
|
||||
<string>Truncate non significant upper digits from frequency scale</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Grid</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/res.qrc">
|
||||
<normaloff>:/truncate.png</normaloff>:/truncate.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="clearSpectrum">
|
||||
<property name="sizePolicy">
|
||||
|
@ -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();
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
#ifndef INCLUDE_SCALEENGINE_H
|
||||
#define INCLUDE_SCALEENGINE_H
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <QFont>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
@ -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);
|
||||
|
@ -1,5 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>truncate.png</file>
|
||||
<file>caliper.png</file>
|
||||
<file>flip_windows.png</file>
|
||||
<file>waterfall_3d.png</file>
|
||||
|
BIN
sdrgui/resources/truncate.png
Normal file
BIN
sdrgui/resources/truncate.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.1 KiB |
BIN
sdrgui/resources/truncate.xcf
Normal file
BIN
sdrgui/resources/truncate.xcf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user