1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-22 08:04:49 -05:00

Use dialog for spectrum measurement settings

This commit is contained in:
Jon Beniston 2022-09-29 11:59:58 +01:00
parent ac64161e66
commit d00862d4f1
15 changed files with 799 additions and 340 deletions

View File

@ -68,14 +68,16 @@ void SpectrumSettings::resetToDefaults()
m_3DSpectrogramStyle = Outline;
m_colorMap = "Angel";
m_spectrumStyle = Line;
m_measure = false;
m_measurement = MeasurementPeaks;
m_measurement = MeasurementNone;
m_measurementCenterFrequencyOffset = 0;
m_measurementBandwidth = 10000;
m_measurementChSpacing = 10000;
m_measurementAdjChBandwidth = 10000;
m_measurementHarmonics = 5;
m_measurementHighlight = true;
m_measurementPeaks = 5;
m_measurementHighlight = true;
m_measurementsPosition = PositionBelow;
m_measurementPrecision = 1;
}
QByteArray SpectrumSettings::serialize() const
@ -123,7 +125,9 @@ QByteArray SpectrumSettings::serialize() const
// 41, 42 used below
s.writeBool(42, m_measurementHighlight);
s.writeS32(43, m_measurementPeaks);
s.writeBool(44, m_measure);
s.writeS32(44, (int)m_measurementsPosition);
s.writeS32(45, m_measurementPrecision);
s.writeS32(46, m_measurementCenterFrequencyOffset);
s.writeS32(100, m_histogramMarkers.size());
for (int i = 0; i < m_histogramMarkers.size(); i++) {
@ -225,14 +229,16 @@ bool SpectrumSettings::deserialize(const QByteArray& data)
d.readS32(32, (int*)&m_3DSpectrogramStyle, (int)Outline);
d.readString(33, &m_colorMap, "Angel");
d.readS32(34, (int*)&m_spectrumStyle, (int)Line);
d.readS32(35, (int*)&m_measurement, (int)MeasurementPeaks);
d.readS32(35, (int*)&m_measurement, (int)MeasurementNone);
d.readS32(36, &m_measurementBandwidth, 10000);
d.readS32(37, &m_measurementChSpacing, 10000);
d.readS32(38, &m_measurementAdjChBandwidth, 10000);
d.readS32(39, &m_measurementHarmonics, 5);
d.readBool(42, &m_measurementHighlight, true);
d.readS32(43, &m_measurementPeaks, 5);
d.readBool(44, &m_measure, false);
d.readS32(44, (int*)&m_measurementsPosition, (int)PositionBelow);
d.readS32(45, &m_measurementPrecision, 1);
d.readS32(46, &m_measurementCenterFrequencyOffset, 0);
int histogramMarkersSize;
d.readS32(100, &histogramMarkersSize, 0);

View File

@ -72,12 +72,20 @@ public:
enum Measurement
{
MeasurementNone,
MeasurementPeaks,
MeasurementChannelPower,
MeasurementAdjacentChannelPower,
MeasurementSNR
};
enum MeasurementsPosition {
PositionAbove,
PositionBelow,
PositionLeft,
PositionRight
};
int m_fftSize;
int m_fftOverlap;
FFTWindow::Function m_fftWindow;
@ -116,14 +124,17 @@ public:
SpectrogramStyle m_3DSpectrogramStyle;
QString m_colorMap;
SpectrumStyle m_spectrumStyle;
bool m_measure;
Measurement m_measurement;
int m_measurementCenterFrequencyOffset;
int m_measurementBandwidth;
int m_measurementChSpacing;
int m_measurementAdjChBandwidth;
int m_measurementHarmonics;
int m_measurementPeaks;
bool m_measurementHighlight;
MeasurementsPosition m_measurementsPosition;
int m_measurementPrecision;
static const int m_log2FFTSizeMin = 6; // 64
static const int m_log2FFTSizeMax = 15; // 32k

View File

@ -70,6 +70,7 @@ set(sdrgui_SOURCES
gui/sdrangelsplash.cpp
gui/spectrumcalibrationpointsdialog.cpp
gui/spectrummarkersdialog.cpp
gui/spectrummeasurementsdialog.cpp
gui/spectrummeasurements.cpp
gui/tickedslider.cpp
gui/timedelegate.cpp
@ -176,6 +177,7 @@ set(sdrgui_HEADERS
gui/sdrangelsplash.h
gui/spectrumcalibrationpointsdialog.h
gui/spectrummarkersdialog.h
gui/spectrummeasurementsdialog.h
gui/spectrummeasurements.h
gui/tickedslider.h
gui/timedelegate.h
@ -243,6 +245,7 @@ set(sdrgui_FORMS
gui/samplingdevicecontrol.ui
gui/samplingdevicedialog.ui
gui/spectrummarkersdialog.ui
gui/spectrummeasurementsdialog.ui
gui/spectrumcalibrationpointsdialog.ui
gui/myposdialog.ui
gui/transverterdialog.ui

View File

@ -111,14 +111,15 @@ GLSpectrum::GLSpectrum(QWidget* parent) :
m_openGLLogger(nullptr),
m_isDeviceSpectrum(false),
m_measurements(nullptr),
m_measure(false),
m_measurement(SpectrumSettings::MeasurementPeaks),
m_measurement(SpectrumSettings::MeasurementNone),
m_measurementCenterFrequencyOffset(0),
m_measurementBandwidth(10000),
m_measurementChSpacing(10000),
m_measurementAdjChBandwidth(10000),
m_measurementHarmonics(5),
m_measurementPeaks(5),
m_measurementHighlight(true)
m_measurementHighlight(true),
m_measurementPrecision(1)
{
// Enable multisampling anti-aliasing (MSAA)
int multisamples = MainCore::instance()->getSettings().getMultisampling();
@ -495,22 +496,23 @@ void GLSpectrum::setUseCalibration(bool useCalibration)
update();
}
void GLSpectrum::setMeasurementParams(bool measure, SpectrumSettings::Measurement measurement,
int bandwidth, int chSpacing, int adjChBandwidth,
int harmonics, int peaks, bool highlight)
void GLSpectrum::setMeasurementParams(SpectrumSettings::Measurement measurement,
int centerFrequencyOffset, int bandwidth, int chSpacing, int adjChBandwidth,
int harmonics, int peaks, bool highlight, int precision)
{
m_mutex.lock();
m_measure = measure;
m_measurement = measurement;
m_measurementCenterFrequencyOffset = centerFrequencyOffset;
m_measurementBandwidth = bandwidth;
m_measurementChSpacing = chSpacing;
m_measurementAdjChBandwidth = adjChBandwidth;
m_measurementHarmonics = harmonics;
m_measurementPeaks = peaks;
m_measurementHighlight = highlight;
m_measurementPrecision = precision;
m_changesPending = true;
if (m_measurements) {
m_measurements->setMeasurementParams(measurement, peaks);
m_measurements->setMeasurementParams(measurement, peaks, precision);
}
m_mutex.unlock();
update();
@ -1681,7 +1683,7 @@ void GLSpectrum::paintGL()
m_glShaderInfo.drawSurface(m_glInfoBoxMatrix, tex1, vtx1, 4);
}
if (m_currentSpectrum && m_measure)
if (m_currentSpectrum)
{
switch (m_measurement)
{
@ -2133,12 +2135,12 @@ void GLSpectrum::measureChannelPower()
{
float power;
power = calcChannelPower(m_centerFrequency, m_measurementBandwidth);
power = calcChannelPower(m_centerFrequency + m_measurementCenterFrequencyOffset, m_measurementBandwidth);
if (m_measurements) {
m_measurements->setChannelPower(power);
}
if (m_measurementHighlight) {
drawBandwidthMarkers(m_centerFrequency, m_measurementBandwidth, m_measurementLightMarkerColor);
drawBandwidthMarkers(m_centerFrequency + m_measurementCenterFrequencyOffset, m_measurementBandwidth, m_measurementLightMarkerColor);
}
}
@ -2147,9 +2149,9 @@ void GLSpectrum::measureAdjacentChannelPower()
{
float power, powerLeft, powerRight;
power = calcChannelPower(m_centerFrequency, m_measurementBandwidth);
powerLeft = calcChannelPower(m_centerFrequency - m_measurementChSpacing, m_measurementAdjChBandwidth);
powerRight = calcChannelPower(m_centerFrequency + m_measurementChSpacing, m_measurementAdjChBandwidth);
power = calcChannelPower(m_centerFrequency + m_measurementCenterFrequencyOffset, m_measurementBandwidth);
powerLeft = calcChannelPower(m_centerFrequency + m_measurementCenterFrequencyOffset - m_measurementChSpacing, m_measurementAdjChBandwidth);
powerRight = calcChannelPower(m_centerFrequency + m_measurementCenterFrequencyOffset + m_measurementChSpacing, m_measurementAdjChBandwidth);
float leftDiff = powerLeft - power;
float rightDiff = powerRight - power;
@ -2160,9 +2162,9 @@ void GLSpectrum::measureAdjacentChannelPower()
if (m_measurementHighlight)
{
drawBandwidthMarkers(m_centerFrequency, m_measurementBandwidth, m_measurementLightMarkerColor);
drawBandwidthMarkers(m_centerFrequency - m_measurementChSpacing, m_measurementAdjChBandwidth, m_measurementDarkMarkerColor);
drawBandwidthMarkers(m_centerFrequency + m_measurementChSpacing, m_measurementAdjChBandwidth, m_measurementDarkMarkerColor);
drawBandwidthMarkers(m_centerFrequency + m_measurementCenterFrequencyOffset, m_measurementBandwidth, m_measurementLightMarkerColor);
drawBandwidthMarkers(m_centerFrequency + m_measurementCenterFrequencyOffset - m_measurementChSpacing, m_measurementAdjChBandwidth, m_measurementDarkMarkerColor);
drawBandwidthMarkers(m_centerFrequency + m_measurementCenterFrequencyOffset + m_measurementChSpacing, m_measurementAdjChBandwidth, m_measurementDarkMarkerColor);
}
}

View File

@ -163,9 +163,9 @@ public:
void setLinear(bool linear);
void setUseCalibration(bool useCalibration);
void setMeasurements(SpectrumMeasurements *measurements) { m_measurements = measurements; }
void setMeasurementParams(bool measure, SpectrumSettings::Measurement measurement,
int bandwidth, int chSpacing, int adjChBandwidth,
int harmonics, int peaks, bool highlight);
void setMeasurementParams(SpectrumSettings::Measurement measurement,
int centerFrequencyOffset, int bandwidth, int chSpacing, int adjChBandwidth,
int harmonics, int peaks, bool highlight, int precision);
qint32 getSampleRate() const { return m_sampleRate; }
void addChannelMarker(ChannelMarker* channelMarker);
@ -378,14 +378,15 @@ private:
bool m_isDeviceSpectrum;
SpectrumMeasurements *m_measurements;
bool m_measure;
SpectrumSettings::Measurement m_measurement;
int m_measurementCenterFrequencyOffset;
int m_measurementBandwidth;
int m_measurementChSpacing;
int m_measurementAdjChBandwidth;
int m_measurementHarmonics;
int m_measurementPeaks;
bool m_measurementHighlight;
int m_measurementPrecision;
static const QVector4D m_measurementLightMarkerColor;
static const QVector4D m_measurementDarkMarkerColor;

View File

@ -33,6 +33,7 @@
#include "gui/wsspectrumsettingsdialog.h"
#include "gui/spectrummarkersdialog.h"
#include "gui/spectrumcalibrationpointsdialog.h"
#include "gui/spectrummeasurementsdialog.h"
#include "gui/spectrummeasurements.h"
#include "gui/flowlayout.h"
#include "util/colormap.h"
@ -54,7 +55,6 @@ GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) :
ui->setupUi(this);
// Use the custom flow layout for the 3 main horizontal layouts (lines)
ui->verticalLayout->removeItem(ui->Line7Layout);
ui->verticalLayout->removeItem(ui->Line6Layout);
ui->verticalLayout->removeItem(ui->Line5Layout);
ui->verticalLayout->removeItem(ui->Line4Layout);
@ -68,11 +68,10 @@ GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) :
flowLayout->addItem(ui->Line4Layout);
flowLayout->addItem(ui->Line5Layout);
flowLayout->addItem(ui->Line6Layout);
flowLayout->addItem(ui->Line7Layout);
ui->verticalLayout->addItem(flowLayout);
on_linscale_toggled(false);
displayMeasurementGUI();
//displayMeasurementGUI();
QString levelStyle = QString(
"QSpinBox {background-color: rgb(79, 79, 79);}"
@ -233,21 +232,13 @@ void GLSpectrumGUI::displaySettings()
ui->calibration->setChecked(m_settings.m_useCalibration);
displayGotoMarkers();
ui->measure->setChecked(m_settings.m_measure);
ui->measurement->setCurrentIndex((int) m_settings.m_measurement);
ui->highlight->setChecked(m_settings.m_measurementHighlight);
ui->bandwidth->setValue(m_settings.m_measurementBandwidth);
ui->chSpacing->setValue(m_settings.m_measurementChSpacing);
ui->adjChBandwidth->setValue(m_settings.m_measurementAdjChBandwidth);
ui->harmonics->setValue(m_settings.m_measurementHarmonics);
ui->peaks->setValue(m_settings.m_measurementPeaks);
displayMeasurementGUI();
ui->fftWindow->blockSignals(false);
ui->averaging->blockSignals(false);
ui->averagingMode->blockSignals(false);
ui->linscale->blockSignals(false);
blockApplySettings(false);
updateMeasurements();
}
void GLSpectrumGUI::displayGotoMarkers()
@ -349,17 +340,6 @@ void GLSpectrumGUI::applySpectrumSettings()
m_glSpectrum->setMarkersDisplay(m_settings.m_markersDisplay);
m_glSpectrum->setCalibrationPoints(m_settings.m_calibrationPoints);
m_glSpectrum->setCalibrationInterpMode(m_settings.m_calibrationInterpMode);
m_glSpectrum->setMeasurementParams(
m_settings.m_measure,
m_settings.m_measurement,
m_settings.m_measurementBandwidth,
m_settings.m_measurementChSpacing,
m_settings.m_measurementAdjChBandwidth,
m_settings.m_measurementHarmonics,
m_settings.m_measurementPeaks,
m_settings.m_measurementHighlight
);
}
void GLSpectrumGUI::on_fftWindow_currentIndexChanged(int index)
@ -1036,95 +1016,39 @@ void GLSpectrumGUI::updateCalibrationPoints()
}
}
void GLSpectrumGUI::displayMeasurementGUI()
{
bool show = m_settings.m_measure;
if (m_glSpectrumTop) {
m_glSpectrumTop->setMeasurementsVisible(show);
}
ui->measurement->setVisible(show);
ui->highlight->setVisible(show);
bool reset = (m_settings.m_measurement >= SpectrumSettings::MeasurementChannelPower);
ui->resetMeasurements->setVisible(reset && show);
bool bw = (m_settings.m_measurement == SpectrumSettings::MeasurementChannelPower)
|| (m_settings.m_measurement == SpectrumSettings::MeasurementAdjacentChannelPower);
ui->bandwidthLabel->setVisible(bw && show);
ui->bandwidth->setVisible(bw && show);
bool adj = m_settings.m_measurement == SpectrumSettings::MeasurementAdjacentChannelPower;
ui->chSpacingLabel->setVisible(adj && show);
ui->chSpacing->setVisible(adj && show);
ui->adjChBandwidthLabel->setVisible(adj && show);
ui->adjChBandwidth->setVisible(adj && show);
bool harmonics = (m_settings.m_measurement == SpectrumSettings::MeasurementSNR);
ui->harmonicsLabel->setVisible(harmonics && show);
ui->harmonics->setVisible(harmonics && show);
bool peaks = (m_settings.m_measurement == SpectrumSettings::MeasurementPeaks);
ui->peaksLabel->setVisible(peaks && show);
ui->peaks->setVisible(peaks && show);
}
void GLSpectrumGUI::on_measure_clicked(bool checked)
{
m_settings.m_measure = checked;
displayMeasurementGUI();
applySettings();
SpectrumMeasurementsDialog measurementsDialog(
m_glSpectrumTop,
&m_settings,
this
);
connect(&measurementsDialog, &SpectrumMeasurementsDialog::updateMeasurements, this, &GLSpectrumGUI::updateMeasurements);
measurementsDialog.exec();
}
void GLSpectrumGUI::on_measurement_currentIndexChanged(int index)
void GLSpectrumGUI::updateMeasurements()
{
m_settings.m_measurement = (SpectrumSettings::Measurement)index;
displayMeasurementGUI();
applySettings();
}
if (m_glSpectrumTop)
{
m_glSpectrumTop->setMeasurementsVisible(m_settings.m_measurement != SpectrumSettings::MeasurementNone);
m_glSpectrumTop->setMeasurementsPosition(m_settings.m_measurementsPosition);
}
void GLSpectrumGUI::on_highlight_toggled(bool checked)
{
m_settings.m_measurementHighlight = checked;
applySettings();
}
void GLSpectrumGUI::on_resetMeasurements_clicked(bool checked)
{
(void) checked;
if (m_glSpectrumTop) {
m_glSpectrumTop->getMeasurements()->reset();
if (m_glSpectrum)
{
m_glSpectrum->setMeasurementParams(
m_settings.m_measurement,
m_settings.m_measurementCenterFrequencyOffset,
m_settings.m_measurementBandwidth,
m_settings.m_measurementChSpacing,
m_settings.m_measurementAdjChBandwidth,
m_settings.m_measurementHarmonics,
m_settings.m_measurementPeaks,
m_settings.m_measurementHighlight,
m_settings.m_measurementPrecision
);
}
}
void GLSpectrumGUI::on_bandwidth_valueChanged(int value)
{
m_settings.m_measurementBandwidth = value;
applySettings();
}
void GLSpectrumGUI::on_chSpacing_valueChanged(int value)
{
m_settings.m_measurementChSpacing = value;
applySettings();
}
void GLSpectrumGUI::on_adjChBandwidth_valueChanged(int value)
{
m_settings.m_measurementAdjChBandwidth = value;
applySettings();
}
void GLSpectrumGUI::on_harmonics_valueChanged(int value)
{
m_settings.m_measurementHarmonics = value;
applySettings();
}
void GLSpectrumGUI::on_peaks_valueChanged(int value)
{
m_settings.m_measurementPeaks = value;
applySettings();
}

View File

@ -88,7 +88,6 @@ private:
bool handleMessage(const Message& message);
void displayGotoMarkers();
QString displayScaled(int64_t value, char type, int precision, bool showMult);
void displayMeasurementGUI();
private slots:
void on_fftWindow_currentIndexChanged(int index);
@ -127,14 +126,6 @@ private slots:
void on_gotoMarker_currentIndexChanged(int index);
void on_measure_clicked(bool checked);
void on_measurement_currentIndexChanged(int index);
void on_highlight_toggled(bool checked);
void on_resetMeasurements_clicked(bool checked);
void on_bandwidth_valueChanged(int value);
void on_chSpacing_valueChanged(int value);
void on_adjChBandwidth_valueChanged(int value);
void on_harmonics_valueChanged(int value);
void on_peaks_valueChanged(int value);
void handleInputMessages();
void openWebsocketSpectrumSettingsDialog(const QPoint& p);
@ -145,6 +136,7 @@ private slots:
void updateAnnotationMarkers();
void updateMarkersDisplay();
void updateCalibrationPoints();
void updateMeasurements();
signals:
// Emitted when user selects an annotation marker

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>630</width>
<height>274</height>
<height>228</height>
</rect>
</property>
<property name="font">
@ -1074,16 +1074,22 @@
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="measure">
<widget class="QPushButton" name="measure">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Display measurements</string>
<string>Open spectrum measurements dialog</string>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/ruler.png</normaloff>:/ruler.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
<bool>false</bool>
</property>
</widget>
</item>
@ -1146,192 +1152,6 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="Line7Layout">
<item>
<widget class="QComboBox" name="measurement">
<property name="toolTip">
<string>Measurement</string>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
<item>
<property name="text">
<string>Peaks</string>
</property>
</item>
<item>
<property name="text">
<string>Ch Power</string>
</property>
</item>
<item>
<property name="text">
<string>Adj Ch</string>
</property>
</item>
<item>
<property name="text">
<string>SNR</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="highlight">
<property name="toolTip">
<string>Highlight measurement</string>
</property>
<property name="text">
<string>Max Hold</string>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/carrier.png</normaloff>:/carrier.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="QToolButton" name="resetMeasurements">
<property name="toolTip">
<string>Reset measurements</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/bin.png</normaloff>:/bin.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="bandwidthLabel">
<property name="text">
<string>B/W</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="bandwidth">
<property name="toolTip">
<string>Measurement bandwidth (Hz)</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100000000</number>
</property>
<property name="singleStep">
<number>1000</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="chSpacingLabel">
<property name="text">
<string>Spacing</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="chSpacing">
<property name="toolTip">
<string>Channel spacing (Hz)</string>
</property>
<property name="maximum">
<number>100000000</number>
</property>
<property name="singleStep">
<number>1000</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="adjChBandwidthLabel">
<property name="text">
<string>Adj. Ch. B/W</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="adjChBandwidth">
<property name="toolTip">
<string>Adjacent channel bandwidth (Hz)</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100000000</number>
</property>
<property name="singleStep">
<number>1000</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="harmonicsLabel">
<property name="text">
<string>Harmonics</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="harmonics">
<property name="toolTip">
<string>Number of harmonics</string>
</property>
<property name="maximum">
<number>20</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="peaksLabel">
<property name="text">
<string>Peaks</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="peaks">
<property name="toolTip">
<string>Number of peaks to display</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>20</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -44,3 +44,27 @@ void GLSpectrumTop::setMeasurementsVisible(bool visible)
{
m_measurements->setVisible(visible);
}
void GLSpectrumTop::setMeasurementsPosition(SpectrumSettings::MeasurementsPosition position)
{
switch (position)
{
case SpectrumSettings::PositionAbove:
m_splitter->setOrientation(Qt::Vertical);
m_splitter->insertWidget(0, m_measurements);
break;
case SpectrumSettings::PositionBelow:
m_splitter->setOrientation(Qt::Vertical);
m_splitter->insertWidget(0, m_spectrum);
break;
case SpectrumSettings::PositionLeft:
m_splitter->setOrientation(Qt::Horizontal);
m_splitter->insertWidget(0, m_measurements);
break;
case SpectrumSettings::PositionRight:
m_splitter->setOrientation(Qt::Horizontal);
m_splitter->insertWidget(0, m_spectrum);
break;
}
}

View File

@ -35,6 +35,7 @@ public:
GLSpectrum *getSpectrum() const { return m_spectrum; }
SpectrumMeasurements *getMeasurements() const { return m_measurements; }
void setMeasurementsVisible(bool visible);
void setMeasurementsPosition(SpectrumSettings::MeasurementsPosition position);
private:
QSplitter *m_splitter;

View File

@ -168,6 +168,7 @@ const QStringList SpectrumMeasurements::m_tooltips = {
SpectrumMeasurements::SpectrumMeasurements(QWidget *parent) :
QWidget(parent),
m_measurement(SpectrumSettings::MeasurementPeaks),
m_precision(1),
m_table(nullptr),
m_peakTable(nullptr)
{
@ -218,7 +219,7 @@ void SpectrumMeasurements::createMeasurementsTable(const QStringList &rows, cons
if (j < COL_COUNT)
{
item->setData(UnitsDelegate::UNITS_ROLE, units[i]);
item->setData(UnitsDelegate::PRECISION_ROLE, 1);
item->setData(UnitsDelegate::PRECISION_ROLE, m_precision);
}
else if (j == COL_SPEC)
{
@ -261,7 +262,7 @@ void SpectrumMeasurements::createPeakTable(int peaks)
item->setData(UnitsDelegate::UNITS_ROLE, "Hz");
} else if (j == COL_POWER) {
item->setData(UnitsDelegate::UNITS_ROLE, " dB");
item->setData(UnitsDelegate::PRECISION_ROLE, 1);
item->setData(UnitsDelegate::PRECISION_ROLE, m_precision);
}
m_peakTable->setItem(i, j, item);
}
@ -453,9 +454,10 @@ void SpectrumMeasurements::resizePeakTable()
m_peakTable->removeRow(row);
}
void SpectrumMeasurements::setMeasurementParams(SpectrumSettings::Measurement measurement, int peaks)
void SpectrumMeasurements::setMeasurementParams(SpectrumSettings::Measurement measurement, int peaks, int precision)
{
if ( (measurement != m_measurement)
if ( (measurement != m_measurement)
|| (m_precision != precision)
|| ((m_peakTable == nullptr) && (m_table == nullptr))
|| ((m_peakTable != nullptr) && (peaks != m_peakTable->rowCount()))
)
@ -467,6 +469,7 @@ void SpectrumMeasurements::setMeasurementParams(SpectrumSettings::Measurement me
m_table = nullptr;
m_measurement = measurement;
m_precision = precision;
switch (measurement)
{

View File

@ -83,7 +83,7 @@ class SDRGUI_API SpectrumMeasurements : public QWidget {
public:
SpectrumMeasurements(QWidget *parent = nullptr);
void setMeasurementParams(SpectrumSettings::Measurement measurement, int peaks);
void setMeasurementParams(SpectrumSettings::Measurement measurement, int peaks, int precision);
void setSNR(float snr, float snfr, float thd, float thdpn, float sinad);
void setSFDR(float sfdr);
void setChannelPower(float power);
@ -111,6 +111,7 @@ private:
bool checkSpec(const QString &spec, double value) const;
SpectrumSettings::Measurement m_measurement;
int m_precision;
QTableWidget *m_table;
QMenu *m_rowMenu;

View File

@ -0,0 +1,173 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2022 Jon Beniston, M7RCE //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QStandardPaths>
#include <QColorDialog>
#include <QFileDialog>
#include "util/db.h"
#include "util/csv.h"
#include "spectrummeasurementsdialog.h"
#include "spectrummeasurements.h"
#include "glspectrumtop.h"
#include "ui_spectrummeasurementsdialog.h"
SpectrumMeasurementsDialog::SpectrumMeasurementsDialog(GLSpectrumTop *glSpectrumTop, SpectrumSettings *settings, QWidget *parent) :
QDialog(parent),
ui(new Ui::SpectrumMeasurementsDialog),
m_glSpectrumTop(glSpectrumTop),
m_settings(settings)
{
ui->setupUi(this);
ui->measurement->setCurrentIndex((int)m_settings->m_measurement);
ui->position->setCurrentIndex((int)m_settings->m_measurementsPosition);
ui->precision->setValue(m_settings->m_measurementPrecision);
ui->highlight->setChecked(m_settings->m_measurementHighlight);
ui->centerFrequencyOffset->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->centerFrequencyOffset->setValueRange(false, 8, -99999999L, 99999999L);
ui->centerFrequencyOffset->setValue(m_settings->m_measurementCenterFrequencyOffset);
ui->bandwidth->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->bandwidth->setValueRange(true, 8, 0L, 99999999L);
ui->bandwidth->setValue(m_settings->m_measurementBandwidth);
ui->chSpacing->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->chSpacing->setValueRange(true, 8, 0L, 99999999L);
ui->chSpacing->setValue(m_settings->m_measurementChSpacing);
ui->adjChBandwidth->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->adjChBandwidth->setValueRange(true, 8, 0L, 99999999L);
ui->adjChBandwidth->setValue(m_settings->m_measurementAdjChBandwidth);
ui->harmonics->setValue(m_settings->m_measurementHarmonics);
ui->peaks->setValue(m_settings->m_measurementPeaks);
displaySettings();
}
SpectrumMeasurementsDialog::~SpectrumMeasurementsDialog()
{}
void SpectrumMeasurementsDialog::displaySettings()
{
bool show = m_settings->m_measurement != SpectrumSettings::MeasurementNone;
ui->positionLabel->setVisible(show);
ui->position->setVisible(show);
ui->precisionLabel->setVisible(show);
ui->precision->setVisible(show);
ui->highlightLabel->setVisible(show);
ui->highlight->setVisible(show);
bool reset = (m_settings->m_measurement >= SpectrumSettings::MeasurementChannelPower);
ui->resetMeasurements->setVisible(reset && show);
bool bw = (m_settings->m_measurement == SpectrumSettings::MeasurementChannelPower)
|| (m_settings->m_measurement == SpectrumSettings::MeasurementAdjacentChannelPower);
ui->centerFrequencyOffsetLabel->setVisible(bw && show);
ui->centerFrequencyOffset->setVisible(bw && show);
ui->bandwidthLabel->setVisible(bw && show);
ui->bandwidth->setVisible(bw && show);
bool adj = m_settings->m_measurement == SpectrumSettings::MeasurementAdjacentChannelPower;
ui->chSpacingLabel->setVisible(adj && show);
ui->chSpacing->setVisible(adj && show);
ui->adjChBandwidthLabel->setVisible(adj && show);
ui->adjChBandwidth->setVisible(adj && show);
bool harmonics = (m_settings->m_measurement == SpectrumSettings::MeasurementSNR);
ui->harmonicsLabel->setVisible(harmonics && show);
ui->harmonics->setVisible(harmonics && show);
bool peaks = (m_settings->m_measurement == SpectrumSettings::MeasurementPeaks);
ui->peaksLabel->setVisible(peaks && show);
ui->peaks->setVisible(peaks && show);
}
void SpectrumMeasurementsDialog::on_measurement_currentIndexChanged(int index)
{
m_settings->m_measurement = (SpectrumSettings::Measurement)index;
displaySettings();
emit updateMeasurements();
}
void SpectrumMeasurementsDialog::on_precision_valueChanged(int value)
{
m_settings->m_measurementPrecision = value;
emit updateMeasurements();
}
void SpectrumMeasurementsDialog::on_position_currentIndexChanged(int index)
{
m_settings->m_measurementsPosition = (SpectrumSettings::MeasurementsPosition)index;
emit updateMeasurements();
}
void SpectrumMeasurementsDialog::on_highlight_toggled(bool checked)
{
m_settings->m_measurementHighlight = checked;
emit updateMeasurements();
}
void SpectrumMeasurementsDialog::on_resetMeasurements_clicked(bool checked)
{
(void) checked;
if (m_glSpectrumTop) {
m_glSpectrumTop->getMeasurements()->reset();
}
}
void SpectrumMeasurementsDialog::on_centerFrequencyOffset_changed(qint64 value)
{
m_settings->m_measurementCenterFrequencyOffset = value;
emit updateMeasurements();
}
void SpectrumMeasurementsDialog::on_bandwidth_changed(qint64 value)
{
m_settings->m_measurementBandwidth = value;
emit updateMeasurements();
}
void SpectrumMeasurementsDialog::on_chSpacing_changed(qint64 value)
{
m_settings->m_measurementChSpacing = value;
emit updateMeasurements();
}
void SpectrumMeasurementsDialog::on_adjChBandwidth_changed(qint64 value)
{
m_settings->m_measurementAdjChBandwidth = value;
emit updateMeasurements();
}
void SpectrumMeasurementsDialog::on_harmonics_valueChanged(int value)
{
m_settings->m_measurementHarmonics = value;
emit updateMeasurements();
}
void SpectrumMeasurementsDialog::on_peaks_valueChanged(int value)
{
m_settings->m_measurementPeaks = value;
emit updateMeasurements();
}

View File

@ -0,0 +1,63 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2022 Jon Beniston, M7RCE //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRBASE_GUI_SPECTRUMMEASUREMENTSDIALOG_H_
#define SDRBASE_GUI_SPECTRUMMEASUREMENTSDIALOG_H_
#include <QDialog>
#include "dsp/spectrumsettings.h"
#include "export.h"
namespace Ui {
class SpectrumMeasurementsDialog;
}
class GLSpectrumTop;
class SDRGUI_API SpectrumMeasurementsDialog : public QDialog {
Q_OBJECT
public:
explicit SpectrumMeasurementsDialog(GLSpectrumTop *glSpectrumTop, SpectrumSettings *settings, QWidget *parent = nullptr);
~SpectrumMeasurementsDialog();
private:
void displaySettings();
Ui::SpectrumMeasurementsDialog *ui;
GLSpectrumTop *m_glSpectrumTop;
SpectrumSettings *m_settings;
private slots:
void on_measurement_currentIndexChanged(int index);
void on_precision_valueChanged(int value);
void on_position_currentIndexChanged(int index);
void on_highlight_toggled(bool checked);
void on_resetMeasurements_clicked(bool checked);
void on_centerFrequencyOffset_changed(qint64 value);
void on_bandwidth_changed(qint64 value);
void on_chSpacing_changed(qint64 value);
void on_adjChBandwidth_changed(qint64 value);
void on_harmonics_valueChanged(int value);
void on_peaks_valueChanged(int value);
signals:
void updateMeasurements();
};
#endif // SDRBASE_GUI_SPECTRUMMEASUREMENTSDIALOG_H_

View File

@ -0,0 +1,435 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SpectrumMeasurementsDialog</class>
<widget class="QDialog" name="SpectrumMeasurementsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>302</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>250</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="windowTitle">
<string>Spectrum Measurements</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QLabel" name="highlightLabel">
<property name="text">
<string>Highlight on spectrum</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QSpinBox" name="harmonics">
<property name="toolTip">
<string>Number of harmonics</string>
</property>
<property name="maximum">
<number>20</number>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="ValueDialZ" name="centerFrequencyOffset" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>DejaVu Sans Mono</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Center frequency offset (Hz)</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="chSpacingLabel">
<property name="text">
<string>Channel spacing</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="position">
<property name="toolTip">
<string>Where to display the measurements result table</string>
</property>
<item>
<property name="text">
<string>Above spectrum</string>
</property>
</item>
<item>
<property name="text">
<string>Below spectrum</string>
</property>
</item>
<item>
<property name="text">
<string>Left of spectrum</string>
</property>
</item>
<item>
<property name="text">
<string>Right of spectrum</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="peaksLabel">
<property name="text">
<string>Peaks</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="centerFrequencyOffsetLabel">
<property name="text">
<string>Center frequency offset</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="measurement">
<property name="toolTip">
<string>Type of measurement</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>Peaks</string>
</property>
</item>
<item>
<property name="text">
<string>Channel power</string>
</property>
</item>
<item>
<property name="text">
<string>Adjacent channel power</string>
</property>
</item>
<item>
<property name="text">
<string>SNR</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="positionLabel">
<property name="text">
<string>Display results table</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="bandwidthLabel">
<property name="text">
<string>Channel bandwidth</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="ValueDialZ" name="chSpacing" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>DejaVu Sans Mono</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Channel spacing (Hz)</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="precisionLabel">
<property name="text">
<string>Results precision</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="ValueDialZ" name="bandwidth" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>DejaVu Sans Mono</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Channel bandwidth (Hz)</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="measurementLabel">
<property name="text">
<string>Measurement</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="highlight">
<property name="toolTip">
<string>Whether to highlight the measurements in the spectrum</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="harmonicsLabel">
<property name="text">
<string>Harmonics</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="peaks">
<property name="toolTip">
<string>Number of peaks to display</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>20</number>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="adjChBandwidthLabel">
<property name="text">
<string>Adjacent channel bandwidth</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="precision">
<property name="toolTip">
<string>Precision of results (number of decimal places)</string>
</property>
<property name="maximum">
<number>9</number>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="ValueDialZ" name="adjChBandwidth" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>DejaVu Sans Mono</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Adjacent channel bandwidth (Hz)</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="resetMeasurements">
<property name="toolTip">
<string>Reset measurement results</string>
</property>
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ValueDialZ</class>
<extends>QWidget</extends>
<header>gui/valuedialz.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>measurement</tabstop>
<tabstop>position</tabstop>
<tabstop>peaks</tabstop>
<tabstop>harmonics</tabstop>
<tabstop>resetMeasurements</tabstop>
</tabstops>
<resources>
<include location="../resources/res.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SpectrumMeasurementsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>194</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>203</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SpectrumMeasurementsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>314</x>
<y>194</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>203</y>
</hint>
</hints>
</connection>
</connections>
</ui>