diff --git a/plugins/samplesink/soapysdroutput/soapysdroutput.cpp b/plugins/samplesink/soapysdroutput/soapysdroutput.cpp index 7e4d4992f..997520360 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutput.cpp +++ b/plugins/samplesink/soapysdroutput/soapysdroutput.cpp @@ -201,6 +201,12 @@ const SoapySDR::RangeList& SoapySDROutput::getBandwidthRanges() return channelSettings->m_bandwidthsRanges; } +const std::vector& SoapySDROutput::getTunableElements() +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel); + return channelSettings->m_frequencySettings; +} + void SoapySDROutput::init() { applySettings(m_settings, true); diff --git a/plugins/samplesink/soapysdroutput/soapysdroutput.h b/plugins/samplesink/soapysdroutput/soapysdroutput.h index 56b21850f..ef848e94a 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutput.h +++ b/plugins/samplesink/soapysdroutput/soapysdroutput.h @@ -103,6 +103,7 @@ public: const SoapySDR::RangeList& getRateRanges(); const std::vector& getAntennas(); const SoapySDR::RangeList& getBandwidthRanges(); + const std::vector& getTunableElements(); private: DeviceSinkAPI *m_deviceAPI; diff --git a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp index 97b6e2de2..5d505c8b8 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp @@ -233,6 +233,12 @@ int SoapySDRInput::getAntennaIndex(const std::string& antenna) } } +const std::vector& SoapySDRInput::getTunableElements() +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); + return channelSettings->m_frequencySettings; +} + void SoapySDRInput::init() { applySettings(m_settings, true); diff --git a/plugins/samplesource/soapysdrinput/soapysdrinput.h b/plugins/samplesource/soapysdrinput/soapysdrinput.h index 5001b1417..212f9f8b7 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinput.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinput.h @@ -125,6 +125,7 @@ public: const SoapySDR::RangeList& getRateRanges(); const SoapySDR::RangeList& getBandwidthRanges(); int getAntennaIndex(const std::string& antenna); + const std::vector& getTunableElements(); private: DeviceSourceAPI *m_deviceAPI; diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp b/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp index 8dea5e21b..4470a31a3 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp @@ -24,6 +24,8 @@ #include "gui/glspectrum.h" #include "soapygui/discreterangegui.h" #include "soapygui/intervalrangegui.h" +#include "soapygui/stringrangegui.h" +#include "soapygui/dynamicitemsettinggui.h" #include "ui_soapysdrinputgui.h" #include "soapysdrinputgui.h" @@ -52,6 +54,7 @@ SoapySDRInputGui::SoapySDRInputGui(DeviceUISet *deviceUISet, QWidget* parent) : createAntennasControl(m_sampleSource->getAntennas()); createRangesControl(&m_sampleRateGUI, m_sampleSource->getRateRanges(), "SR", "S/s"); createRangesControl(&m_bandwidthGUI, m_sampleSource->getBandwidthRanges(), "BW", "Hz"); + createTunableElementsControl(m_sampleSource->getTunableElements()); if (m_sampleRateGUI) { connect(m_sampleRateGUI, SIGNAL(valueChanged(double)), this, SLOT(sampleRateChanged(double))); @@ -156,6 +159,24 @@ void SoapySDRInputGui::createAntennasControl(const std::vector& ant connect(m_antennas, SIGNAL(valueChanged()), this, SLOT(antennasChanged())); } +void SoapySDRInputGui::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("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 SoapySDRInputGui::setName(const QString& name) { setObjectName(name); @@ -278,6 +299,11 @@ void SoapySDRInputGui::bandwidthChanged(double bandwidth) sendSettings(); } +void SoapySDRInputGui::tunableElementChanged(QString name, double value) +{ + qDebug("SoapySDRInputGui::tunableElementChanged: name: %s value: %lf", name.toStdString().c_str(), value); +} + void SoapySDRInputGui::on_centerFrequency_changed(quint64 value) { m_settings.m_centerFrequency = value * 1000; diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.h b/plugins/samplesource/soapysdrinput/soapysdrinputgui.h index 7a1ab29d4..deaee34a5 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.h @@ -17,18 +17,19 @@ #ifndef PLUGINS_SAMPLESOURCE_SOAPYSDRINPUT_SOAPYSDRINPUTGUI_H_ #define PLUGINS_SAMPLESOURCE_SOAPYSDRINPUT_SOAPYSDRINPUTGUI_H_ -#include #include #include #include #include "plugin/plugininstancegui.h" #include "util/messagequeue.h" + #include "soapysdrinput.h" class DeviceUISet; class ItemSettingGUI; class StringRangeGUI; +class DynamicItemSettingGUI; namespace Ui { class SoapySDRInputGui; @@ -60,6 +61,7 @@ private: const QString& text, const QString& unit); void createAntennasControl(const std::vector& antennaList); + void createTunableElementsControl(const std::vector& tunableElementsList); Ui::SoapySDRInputGui* ui; @@ -78,6 +80,7 @@ private: StringRangeGUI *m_antennas; ItemSettingGUI *m_sampleRateGUI; ItemSettingGUI *m_bandwidthGUI; + std::vector m_tunableElementsGUIs; void displaySettings(); void sendSettings(); @@ -90,6 +93,7 @@ private slots: void handleInputMessages(); void sampleRateChanged(double sampleRate); void antennasChanged(); + void tunableElementChanged(QString name, double value); void bandwidthChanged(double bandwidth); void on_centerFrequency_changed(quint64 value); void on_LOppm_valueChanged(int value); diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp index 9489947b9..46f999cc4 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp @@ -14,6 +14,8 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// +#include + #include "util/simpleserializer.h" #include "soapysdrinputsettings.h" @@ -53,6 +55,7 @@ QByteArray SoapySDRInputSettings::serialize() const s.writeS64(8, m_transverterDeltaFrequency); s.writeString(9, m_antenna); s.writeU32(10, m_bandwidth); + s.writeBlob(11, serializeNamedElementMap(m_tunableElements)); return s.final(); } @@ -70,6 +73,7 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data) if (d.getVersion() == 1) { int intval; + QByteArray blob; d.readS32(1, &m_devSampleRate, 1024000); d.readU32(2, &m_log2Decim); @@ -82,6 +86,8 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data) d.readS64(8, &m_transverterDeltaFrequency, 0); d.readString(9, &m_antenna, "NONE"); d.readU32(10, &m_bandwidth, 1000000); + d.readBlob(11, &blob); + deserializeNamedElementMap(blob, m_tunableElements); return true; } @@ -91,3 +97,20 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data) return false; } } + +QByteArray SoapySDRInputSettings::serializeNamedElementMap(const QMap& map) const +{ + QByteArray data; + QDataStream *stream = new QDataStream(&data, QIODevice::WriteOnly); + (*stream) << map; + delete stream; + + return data; +} + +void SoapySDRInputSettings::deserializeNamedElementMap(const QByteArray& data, QMap& map) +{ + QDataStream *stream = new QDataStream(data); + (*stream) >> map; + delete stream; +} diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h index 62a942814..a74f0bc92 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h @@ -19,6 +19,7 @@ #include #include +#include struct SoapySDRInputSettings { typedef enum { @@ -39,11 +40,16 @@ struct SoapySDRInputSettings { QString m_fileRecordName; QString m_antenna; quint32 m_bandwidth; + QMap m_tunableElements; SoapySDRInputSettings(); 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_SAMPLESOURCE_SOAPYSDRINPUT_SOAPYSDRINPUTSETTINGS_H_ */ diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt index 709164adf..cede779da 100644 --- a/sdrgui/CMakeLists.txt +++ b/sdrgui/CMakeLists.txt @@ -45,20 +45,21 @@ set(sdrgui_SOURCES gui/tvscreen.cpp gui/valuedial.cpp gui/valuedialz.cpp - + dsp/scopevis.cpp dsp/scopevismulti.cpp dsp/scopevisxy.cpp dsp/spectrumvis.cpp dsp/spectrumscopecombovis.cpp - + device/deviceuiset.cpp - + soapygui/discreterangegui.cpp soapygui/intervalrangegui.cpp soapygui/itemsettinggui.cpp soapygui/stringrangegui.cpp - + soapygui/dynamicitemsettinggui.cpp + webapi/webapiadaptergui.cpp ) @@ -92,7 +93,7 @@ set(sdrgui_HEADERS gui/glspectrumgui.h gui/indicator.h gui/levelmeter.h - gui/loggingdialog.h + gui/loggingdialog.h gui/mypositiondialog.h gui/physicalunit.h gui/pluginsdialog.h @@ -104,23 +105,24 @@ set(sdrgui_HEADERS gui/tickedslider.h gui/transverterbutton.h gui/transverterdialog.h - gui/tvscreen.h + gui/tvscreen.h gui/valuedial.h gui/valuedialz.h - + dsp/scopevis.h dsp/scopevismulti.h - dsp/scopevisxy.h + dsp/scopevisxy.h dsp/spectrumvis.h dsp/spectrumscopecombovis.h - + device/deviceuiset.h - + soapygui/discreterangegui.h soapygui/intervalrangegui.h soapygui/itemsettinggui.h soapygui/stringrangegui.h - + soapygui/dynamicitemsettinggui.h + webapi/webapiadaptergui.h ) @@ -180,7 +182,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/sdrbase ${CMAKE_SOURCE_DIR}/logging ${CMAKE_SOURCE_DIR}/httpserver - ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client + ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client ${CMAKE_CURRENT_BINARY_DIR} ${OPENGL_INCLUDE_DIR} ) diff --git a/sdrgui/soapygui/dynamicitemsettinggui.cpp b/sdrgui/soapygui/dynamicitemsettinggui.cpp new file mode 100644 index 000000000..d457c701c --- /dev/null +++ b/sdrgui/soapygui/dynamicitemsettinggui.cpp @@ -0,0 +1,34 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Edouard Griffiths, F4EXB // +// // +// 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 // +// // +// 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "dynamicitemsettinggui.h" + +DynamicItemSettingGUI::DynamicItemSettingGUI(ItemSettingGUI *itemSettingGUI, const QString& name, QObject *parent) : + QObject(parent), + m_itemSettingGUI(itemSettingGUI), + m_name(name) +{ + connect(m_itemSettingGUI, SIGNAL(valueChanged(double)), this, SLOT(processValueChanged(double))); +} + +DynamicItemSettingGUI::~DynamicItemSettingGUI() +{ + disconnect(m_itemSettingGUI, SIGNAL(valueChanged(double)), this, SLOT(processValueChanged(double))); +} + +void DynamicItemSettingGUI::processValueChanged(double value) { + emit valueChanged(m_name, value); +} diff --git a/sdrgui/soapygui/dynamicitemsettinggui.h b/sdrgui/soapygui/dynamicitemsettinggui.h new file mode 100644 index 000000000..2a197ba44 --- /dev/null +++ b/sdrgui/soapygui/dynamicitemsettinggui.h @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Edouard Griffiths, F4EXB // +// // +// 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 // +// // +// 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include "itemsettinggui.h" + +class DynamicItemSettingGUI : public QObject +{ + Q_OBJECT +public: + DynamicItemSettingGUI(ItemSettingGUI *itemSettingGUI, const QString& name, QObject *parent = 0); + ~DynamicItemSettingGUI(); + + const QString& getName() const { return m_name; } + double getValue() const { return m_itemSettingGUI->getCurrentValue(); } + +signals: + void valueChanged(QString itemName, double value); + +private slots: + void processValueChanged(double value); + +private: + ItemSettingGUI *m_itemSettingGUI; + QString m_name; +}; \ No newline at end of file