From 66f95bc0a66cf290fd69a28a0747be8c7d458442 Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 8 Nov 2018 14:35:26 +0100 Subject: [PATCH] SoapySDR support: input: auto correction GUIs (1) --- .../soapysdrinput/soapysdrinput.cpp | 28 ++++++-- .../soapysdrinput/soapysdrinput.h | 4 ++ .../soapysdrinput/soapysdrinputgui.cpp | 66 +++++++++++++++++-- .../soapysdrinput/soapysdrinputgui.h | 13 ++++ .../soapysdrinput/soapysdrinputsettings.cpp | 22 ++++--- .../soapysdrinput/soapysdrinputsettings.h | 8 ++- 6 files changed, 121 insertions(+), 20 deletions(-) diff --git a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp index 556d72687..a74f111f2 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp @@ -282,6 +282,24 @@ void SoapySDRInput::initGainSettings(SoapySDRInputSettings& settings) updateGains(m_deviceShared.m_device, m_deviceShared.m_channel, settings); } +bool SoapySDRInput::hasDCAutoCorrection() +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); + return channelSettings->m_hasDCAutoCorrection; +} + +bool SoapySDRInput::hasDCCorrectionValue() +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); + return channelSettings->m_hasDCOffsetValue; +} + +bool SoapySDRInput::hasIQCorrectionValue() +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); + return channelSettings->m_hasIQBalanceValue; +} + void SoapySDRInput::init() { applySettings(m_settings, true); @@ -753,10 +771,10 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo xlatedDeviceCenterFrequency -= settings.m_transverterMode ? settings.m_transverterDeltaFrequency : 0; xlatedDeviceCenterFrequency = xlatedDeviceCenterFrequency < 0 ? 0 : xlatedDeviceCenterFrequency; - if ((m_settings.m_dcBlock != settings.m_dcBlock) || - (m_settings.m_iqCorrection != settings.m_iqCorrection) || force) + if ((m_settings.m_softDCCorrection != settings.m_softDCCorrection) || + (m_settings.m_softIQCorrection != settings.m_softIQCorrection) || force) { - m_deviceAPI->configureCorrections(settings.m_dcBlock, settings.m_iqCorrection); + m_deviceAPI->configureCorrections(settings.m_softDCCorrection, settings.m_softIQCorrection); } if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force) @@ -1015,8 +1033,8 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo << " m_log2Decim: " << m_settings.m_log2Decim << " m_fcPos: " << m_settings.m_fcPos << " m_devSampleRate: " << m_settings.m_devSampleRate - << " m_dcBlock: " << m_settings.m_dcBlock - << " m_iqCorrection: " << m_settings.m_iqCorrection + << " m_softDCCorrection: " << m_settings.m_softDCCorrection + << " m_softIQCorrection: " << m_settings.m_softIQCorrection << " m_antenna: " << m_settings.m_antenna << " m_bandwidth: " << m_settings.m_bandwidth << " m_globalGain: " << m_settings.m_globalGain; diff --git a/plugins/samplesource/soapysdrinput/soapysdrinput.h b/plugins/samplesource/soapysdrinput/soapysdrinput.h index 849e5783d..d18c5194e 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinput.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinput.h @@ -156,6 +156,10 @@ public: const std::vector& getTunableElements(); const std::vector& getIndividualGainsRanges(); void initGainSettings(SoapySDRInputSettings& settings); + bool hasDCAutoCorrection(); + bool hasDCCorrectionValue(); + bool hasIQAutoCorrection() { return false; } // not in SoapySDR interface + bool hasIQCorrectionValue(); private: DeviceSourceAPI *m_deviceAPI; diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp b/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp index 49caee713..b29b57fda 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp @@ -28,6 +28,7 @@ #include "soapygui/stringrangegui.h" #include "soapygui/dynamicitemsettinggui.h" #include "soapygui/intervalslidergui.h" +#include "soapygui/complexfactorgui.h" #include "ui_soapysdrinputgui.h" #include "soapysdrinputgui.h" @@ -46,7 +47,11 @@ SoapySDRInputGui::SoapySDRInputGui(DeviceUISet *deviceUISet, QWidget* parent) : m_sampleRateGUI(0), m_bandwidthGUI(0), m_gainSliderGUI(0), - m_autoGain(0) + m_autoGain(0), + m_dcCorrectionGUI(0), + m_iqCorrectionGUI(0), + m_autoDCCorrection(0), + m_autoIQCorrection(0) { m_sampleSource = (SoapySDRInput*) m_deviceUISet->m_deviceSourceAPI->getSampleSource(); ui->setupUi(this); @@ -241,6 +246,57 @@ void SoapySDRInputGui::createIndividualGainsControl(const std::vectorscrollAreaWidgetContents->layout(); + + if (m_sampleSource->hasDCCorrectionValue()) // complex GUI + { + m_dcCorrectionGUI = new ComplexFactorGUI(this); + m_dcCorrectionGUI->setLabel(QString("DC")); + m_dcCorrectionGUI->setAutomaticEnable(m_sampleSource->hasDCAutoCorrection()); + layout->addWidget(m_dcCorrectionGUI); + + connect(m_dcCorrectionGUI, SIGNAL(moduleChanged(double)), this, SLOT(dcCorrectionModuleChanged(double))); + connect(m_dcCorrectionGUI, SIGNAL(argumentChanged(double)), this, SLOT(dcCorrectionArgumentChanged(double))); + + if (m_sampleSource->hasDCAutoCorrection()) { + connect(m_dcCorrectionGUI, SIGNAL(automaticChanged(bool)), this, SLOT(autoDCCorrectionChanged(bool))); + } + } + else if (m_sampleSource->hasDCAutoCorrection()) // simple checkbox + { + m_autoDCCorrection = new QCheckBox(this); + m_autoDCCorrection->setText(QString("DC corr")); + layout->addWidget(m_autoDCCorrection); + + connect(m_autoDCCorrection, SIGNAL(toggled(bool)), this, SLOT(autoDCCorrectionChanged(bool))); + } + + if (m_sampleSource->hasIQCorrectionValue()) // complex GUI + { + m_iqCorrectionGUI = new ComplexFactorGUI(this); + m_iqCorrectionGUI->setLabel(QString("IQ")); + m_iqCorrectionGUI->setAutomaticEnable(m_sampleSource->hasIQAutoCorrection()); + layout->addWidget(m_iqCorrectionGUI); + + connect(m_iqCorrectionGUI, SIGNAL(moduleChanged(double)), this, SLOT(iqCorrectionModuleChanged(double))); + connect(m_iqCorrectionGUI, SIGNAL(argumentChanged(double)), this, SLOT(iqCorrectionArgumentChanged(double))); + + if (m_sampleSource->hasIQAutoCorrection()) { + connect(m_iqCorrectionGUI, SIGNAL(automaticChanged(bool)), this, SLOT(autoIQCorrectionChanged(bool))); + } + } + else if (m_sampleSource->hasIQAutoCorrection()) // simple checkbox + { + m_autoIQCorrection = new QCheckBox(this); + m_autoIQCorrection->setText(QString("IQ corr")); + layout->addWidget(m_autoIQCorrection); + + connect(m_autoIQCorrection, SIGNAL(toggled(bool)), this, SLOT(autoIQCorrectionChanged(bool))); + } +} + void SoapySDRInputGui::setName(const QString& name) { setObjectName(name); @@ -413,13 +469,13 @@ void SoapySDRInputGui::on_centerFrequency_changed(quint64 value) void SoapySDRInputGui::on_dcOffset_toggled(bool checked) { - m_settings.m_dcBlock = checked; + m_settings.m_softDCCorrection = checked; sendSettings(); } void SoapySDRInputGui::on_iqImbalance_toggled(bool checked) { - m_settings.m_iqCorrection = checked; + m_settings.m_softIQCorrection = checked; sendSettings(); } @@ -506,8 +562,8 @@ void SoapySDRInputGui::displaySettings() m_autoGain->setChecked(m_settings.m_autoGain); } - ui->dcOffset->setChecked(m_settings.m_dcBlock); - ui->iqImbalance->setChecked(m_settings.m_iqCorrection); + ui->dcOffset->setChecked(m_settings.m_softDCCorrection); + ui->iqImbalance->setChecked(m_settings.m_softIQCorrection); ui->decim->setCurrentIndex(m_settings.m_log2Decim); ui->fcPos->setCurrentIndex((int) m_settings.m_fcPos); diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.h b/plugins/samplesource/soapysdrinput/soapysdrinputgui.h index 65fd3a916..9e0e6bc5e 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.h @@ -31,6 +31,7 @@ class StringRangeGUI; class DynamicItemSettingGUI; class IntervalSliderGUI; class QCheckBox; +class ComplexFactorGUI; namespace Ui { class SoapySDRInputGui; @@ -65,6 +66,7 @@ private: void createTunableElementsControl(const std::vector& tunableElementsList); void createGlobalGainControl(); void createIndividualGainsControl(const std::vector& individualGainsList); + void createCorrectionsControl(); Ui::SoapySDRInputGui* ui; @@ -87,6 +89,10 @@ private: IntervalSliderGUI *m_gainSliderGUI; std::vector m_individualGainsGUIs; QCheckBox *m_autoGain; + ComplexFactorGUI *m_dcCorrectionGUI; + ComplexFactorGUI *m_iqCorrectionGUI; + QCheckBox *m_autoDCCorrection; + QCheckBox *m_autoIQCorrection; void displaySettings(); void displayTunableElementsControlSettings(); @@ -106,6 +112,13 @@ private slots: void globalGainChanged(double gain); void autoGainChanged(bool set); void individualGainChanged(QString name, double value); + void autoDCCorrectionChanged(bool set); + void autoIQCorrectionChanged(bool set); + void dcCorrectionModuleChanged(double value); + void dcCorrectionArgumentChanged(double value); + void iqCorrectionModuleChanged(double value); + void iqCorrectionArgumentChanged(double value); + void on_centerFrequency_changed(quint64 value); void on_LOppm_valueChanged(int value); void on_dcOffset_toggled(bool checked); diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp index 6614e596c..7ae9780bf 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp @@ -32,8 +32,8 @@ void SoapySDRInputSettings::resetToDefaults() m_devSampleRate = 1024000; m_log2Decim = 0; m_fcPos = FC_POS_CENTER; - m_dcBlock = false; - m_iqCorrection = false; + m_softDCCorrection = false; + m_softIQCorrection = false; m_transverterMode = false; m_transverterDeltaFrequency = 0; m_fileRecordName = ""; @@ -41,6 +41,8 @@ void SoapySDRInputSettings::resetToDefaults() m_bandwidth = 1000000; m_globalGain = 0; m_autoGain = false; + m_autoDCCorrection = false; + m_autoIQCorrection = false; } QByteArray SoapySDRInputSettings::serialize() const @@ -50,8 +52,8 @@ QByteArray SoapySDRInputSettings::serialize() const s.writeS32(1, m_devSampleRate); s.writeU32(2, m_log2Decim); s.writeS32(3, (int) m_fcPos); - s.writeBool(4, m_dcBlock); - s.writeBool(5, m_iqCorrection); + s.writeBool(4, m_softDCCorrection); + s.writeBool(5, m_softIQCorrection); s.writeS32(6, m_LOppmTenths); s.writeBool(7, m_transverterMode); s.writeS64(8, m_transverterDeltaFrequency); @@ -61,6 +63,8 @@ QByteArray SoapySDRInputSettings::serialize() const s.writeS32(12, m_globalGain); s.writeBlob(13, serializeNamedElementMap(m_individualGains)); s.writeBool(14, m_autoGain); + s.writeBool(15, m_autoDCCorrection); + s.writeBool(16, m_autoIQCorrection); return s.final(); } @@ -81,12 +85,12 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data) QByteArray blob; d.readS32(1, &m_devSampleRate, 1024000); - d.readU32(2, &m_log2Decim); + d.readU32(2, &m_log2Decim, 0); d.readS32(3, &intval, (int) FC_POS_CENTER); m_fcPos = (fcPos_t) intval; - d.readBool(4, &m_dcBlock); - d.readBool(5, &m_iqCorrection); - d.readS32(6, &m_LOppmTenths); + d.readBool(4, &m_softDCCorrection, false); + d.readBool(5, &m_softIQCorrection, false); + d.readS32(6, &m_LOppmTenths, 0); d.readBool(7, &m_transverterMode, false); d.readS64(8, &m_transverterDeltaFrequency, 0); d.readString(9, &m_antenna, "NONE"); @@ -97,6 +101,8 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data) d.readBlob(13, &blob); deserializeNamedElementMap(blob, m_individualGains); d.readBool(14, &m_autoGain, false); + d.readBool(15, &m_autoDCCorrection, false); + d.readBool(16, &m_autoIQCorrection, false); return true; } diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h index 67623834c..f2df1821b 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h @@ -33,8 +33,8 @@ struct SoapySDRInputSettings { qint32 m_devSampleRate; quint32 m_log2Decim; fcPos_t m_fcPos; - bool m_dcBlock; - bool m_iqCorrection; + bool m_softDCCorrection; + bool m_softIQCorrection; bool m_transverterMode; qint64 m_transverterDeltaFrequency; QString m_fileRecordName; @@ -44,6 +44,10 @@ struct SoapySDRInputSettings { qint32 m_globalGain; QMap m_individualGains; bool m_autoGain; + bool m_autoDCCorrection; + bool m_autoIQCorrection; + std::complex m_dcCorrection; + std::complex m_iqCorrection; SoapySDRInputSettings(); void resetToDefaults();