From e17828c7ee4cac8017c33e186e5e13221e3e8daf Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 6 Nov 2018 20:19:20 +0100 Subject: [PATCH] SoapySDR support: output: tunable elements GUIs --- .../soapysdroutput/soapysdroutput.cpp | 25 +++++++++++ .../soapysdroutput/soapysdroutputgui.cpp | 42 +++++++++++++++++++ .../soapysdroutput/soapysdroutputgui.h | 7 +++- .../soapysdroutput/soapysdroutputsettings.cpp | 24 +++++++++++ .../soapysdroutput/soapysdroutputsettings.h | 6 +++ .../soapysdrinput/soapysdrinputgui.cpp | 1 - .../soapysdrinput/soapysdrinputgui.h | 4 +- 7 files changed, 105 insertions(+), 4 deletions(-) diff --git a/plugins/samplesink/soapysdroutput/soapysdroutput.cpp b/plugins/samplesink/soapysdroutput/soapysdroutput.cpp index 997520360..45496b3a2 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutput.cpp +++ b/plugins/samplesink/soapysdroutput/soapysdroutput.cpp @@ -766,6 +766,31 @@ bool SoapySDROutput::applySettings(const SoapySDROutputSettings& settings, bool } } + for (const auto &oname : m_settings.m_tunableElements.keys()) + { + auto nvalue = settings.m_tunableElements.find(oname); + + if (nvalue != settings.m_tunableElements.end() && (m_settings.m_tunableElements[oname] != *nvalue)) + { + if (dev != 0) + { + try + { + dev->setFrequency(SOAPY_SDR_TX, requestedChannel, oname.toStdString(), *nvalue); + qDebug("SoapySDROutput::applySettings: tunable element %s frequency set to %lf", + oname.toStdString().c_str(), *nvalue); + } + catch (const std::exception &ex) + { + qCritical("SoapySDROutput::applySettings: cannot set tunable element %s to %lf: %s", + oname.toStdString().c_str(), *nvalue, ex.what()); + } + } + + m_settings.m_tunableElements[oname] = *nvalue; + } + } + if (forwardChangeOwnDSP) { int sampleRate = settings.m_devSampleRate/(1<& an connect(m_antennas, SIGNAL(valueChanged()), this, SLOT(antennasChanged())); } +void SoapySDROutputGui::createTunableElementsControl(const std::vector& tunableElementsList) +{ + if (tunableElementsList.size() <= 1) { // This list is created for other elements than the main one (RF) which is always at index 0 + return; + } + + std::vector::const_iterator it = tunableElementsList.begin() + 1; + + for (int i = 0; it != tunableElementsList.end(); ++it, i++) + { + ItemSettingGUI *rangeGUI; + createRangesControl( + &rangeGUI, + it->m_ranges, + QString("%1 freq").arg(it->m_name.c_str()), + QString((it->m_name == "CORR") ? "ppm" : "Hz")); + DynamicItemSettingGUI *gui = new DynamicItemSettingGUI(rangeGUI, QString(it->m_name.c_str())); + m_tunableElementsGUIs.push_back(gui); + connect(m_tunableElementsGUIs.back(), SIGNAL(valueChanged(QString, double)), this, SLOT(tunableElementChanged(QString, double))); + } +} + void SoapySDROutputGui::setName(const QString& name) { setObjectName(name); @@ -279,6 +302,11 @@ void SoapySDROutputGui::bandwidthChanged(double bandwidth) sendSettings(); } +void SoapySDROutputGui::tunableElementChanged(QString name, double value) +{ + m_settings.m_tunableElements[name] = value; + sendSettings(); +} void SoapySDROutputGui::on_centerFrequency_changed(quint64 value) { @@ -341,9 +369,23 @@ void SoapySDROutputGui::displaySettings() ui->LOppm->setValue(m_settings.m_LOppmTenths); ui->LOppmText->setText(QString("%1").arg(QString::number(m_settings.m_LOppmTenths/10.0, 'f', 1))); + displayTunableElementsControlSettings(); + blockApplySettings(false); } +void SoapySDROutputGui::displayTunableElementsControlSettings() +{ + for (const auto &it : m_tunableElementsGUIs) + { + QMap::const_iterator elIt = m_settings.m_tunableElements.find(it->getName()); + + if (elIt != m_settings.m_tunableElements.end()) { + it->setValue(*elIt); + } + } +} + void SoapySDROutputGui::sendSettings() { if (!m_updateTimer.isActive()) { diff --git a/plugins/samplesink/soapysdroutput/soapysdroutputgui.h b/plugins/samplesink/soapysdroutput/soapysdroutputgui.h index fe460e29e..4123231a5 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutputgui.h +++ b/plugins/samplesink/soapysdroutput/soapysdroutputgui.h @@ -30,6 +30,7 @@ class DeviceSampleSink; class DeviceUISet; class ItemSettingGUI; class StringRangeGUI; +class DynamicItemSettingGUI; namespace Ui { class SoapySDROutputGui; @@ -61,6 +62,7 @@ private: const QString& text, const QString& unit); void createAntennasControl(const std::vector& antennaList); + void createTunableElementsControl(const std::vector& tunableElementsList); Ui::SoapySDROutputGui* ui; @@ -79,9 +81,11 @@ private: StringRangeGUI *m_antennas; ItemSettingGUI *m_sampleRateGUI; ItemSettingGUI *m_bandwidthGUI; + std::vector m_tunableElementsGUIs; void blockApplySettings(bool block) { m_doApplySettings = !block; } void displaySettings(); + void displayTunableElementsControlSettings(); void sendSettings(); void updateSampleRateAndFrequency(); void updateFrequencyLimits(); @@ -89,9 +93,10 @@ private: private slots: void handleInputMessages(); - void sampleRateChanged(double sampleRate); void antennasChanged(); + void sampleRateChanged(double sampleRate); void bandwidthChanged(double bandwidth); + void tunableElementChanged(QString name, double value); void on_centerFrequency_changed(quint64 value); void on_LOppm_valueChanged(int value); void on_interp_currentIndexChanged(int index); diff --git a/plugins/samplesink/soapysdroutput/soapysdroutputsettings.cpp b/plugins/samplesink/soapysdroutput/soapysdroutputsettings.cpp index 2efd42e74..7e5dd37f7 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutputsettings.cpp +++ b/plugins/samplesink/soapysdroutput/soapysdroutputsettings.cpp @@ -15,6 +15,8 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#include + #include "util/simpleserializer.h" #include "soapysdroutputsettings.h" @@ -47,6 +49,7 @@ QByteArray SoapySDROutputSettings::serialize() const s.writeS64(5, m_transverterDeltaFrequency); s.writeString(6, m_antenna); s.writeU32(7, m_bandwidth); + s.writeBlob(8, serializeNamedElementMap(m_tunableElements)); return s.final(); } @@ -63,6 +66,8 @@ bool SoapySDROutputSettings::deserialize(const QByteArray& data) if (d.getVersion() == 1) { + QByteArray blob; + d.readS32(1, &m_devSampleRate); d.readS32(2, &m_LOppmTenths); d.readU32(3, &m_log2Interp); @@ -70,6 +75,8 @@ bool SoapySDROutputSettings::deserialize(const QByteArray& data) d.readS64(5, &m_transverterDeltaFrequency, 0); d.readString(6, &m_antenna, "NONE"); d.readU32(7, &m_bandwidth, 1000000); + d.readBlob(8, &blob); + deserializeNamedElementMap(blob, m_tunableElements); return true; } @@ -79,3 +86,20 @@ bool SoapySDROutputSettings::deserialize(const QByteArray& data) return false; } } + +QByteArray SoapySDROutputSettings::serializeNamedElementMap(const QMap& map) const +{ + QByteArray data; + QDataStream *stream = new QDataStream(&data, QIODevice::WriteOnly); + (*stream) << map; + delete stream; + + return data; +} + +void SoapySDROutputSettings::deserializeNamedElementMap(const QByteArray& data, QMap& map) +{ + QDataStream *stream = new QDataStream(data); + (*stream) >> map; + delete stream; +} \ No newline at end of file diff --git a/plugins/samplesink/soapysdroutput/soapysdroutputsettings.h b/plugins/samplesink/soapysdroutput/soapysdroutputsettings.h index 9e368bc45..21b9ade24 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutputsettings.h +++ b/plugins/samplesink/soapysdroutput/soapysdroutputsettings.h @@ -18,6 +18,7 @@ #define PLUGINS_SAMPLESINK_SOAPYSDROUTPUT_SOAPYSDROUTPUTSETTINGS_H_ #include +#include struct SoapySDROutputSettings { quint64 m_centerFrequency; @@ -28,11 +29,16 @@ struct SoapySDROutputSettings { qint64 m_transverterDeltaFrequency; QString m_antenna; quint32 m_bandwidth; + QMap m_tunableElements; SoapySDROutputSettings(); void resetToDefaults(); QByteArray serialize() const; bool deserialize(const QByteArray& data); + +private: + QByteArray serializeNamedElementMap(const QMap& map) const; + void deserializeNamedElementMap(const QByteArray& data, QMap& map); }; #endif /* PLUGINS_SAMPLESINK_SOAPYSDROUTPUT_SOAPYSDROUTPUTSETTINGS_H_ */ diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp b/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp index 7411a78c5..a3649468f 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp @@ -306,7 +306,6 @@ void SoapySDRInputGui::bandwidthChanged(double bandwidth) void SoapySDRInputGui::tunableElementChanged(QString name, double value) { - qDebug("SoapySDRInputGui::tunableElementChanged: name: %s value: %lf", name.toStdString().c_str(), value); m_settings.m_tunableElements[name] = value; sendSettings(); } diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.h b/plugins/samplesource/soapysdrinput/soapysdrinputgui.h index b965b7517..0a0233dc8 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.h @@ -92,10 +92,10 @@ private: private slots: void handleInputMessages(); - void sampleRateChanged(double sampleRate); void antennasChanged(); - void tunableElementChanged(QString name, double value); + void sampleRateChanged(double sampleRate); void bandwidthChanged(double bandwidth); + void tunableElementChanged(QString name, double value); void on_centerFrequency_changed(quint64 value); void on_LOppm_valueChanged(int value); void on_dcOffset_toggled(bool checked);