From d7be0927b1002bdec8ce44784de5b226e7429339 Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 7 Nov 2018 01:33:17 +0100 Subject: [PATCH] SoapySDR support: input: global gain GUI --- .../soapysdrinput/soapysdrinput.cpp | 44 +++++++++- .../soapysdrinput/soapysdrinput.h | 2 + .../soapysdrinput/soapysdrinputgui.cpp | 29 ++++++- .../soapysdrinput/soapysdrinputgui.h | 4 + .../soapysdrinput/soapysdrinputsettings.cpp | 3 + .../soapysdrinput/soapysdrinputsettings.h | 1 + sdrgui/CMakeLists.txt | 3 + sdrgui/soapygui/intervalslidergui.cpp | 71 ++++++++++++++++ sdrgui/soapygui/intervalslidergui.h | 52 ++++++++++++ sdrgui/soapygui/intervalslidergui.ui | 83 +++++++++++++++++++ 10 files changed, 289 insertions(+), 3 deletions(-) create mode 100644 sdrgui/soapygui/intervalslidergui.cpp create mode 100644 sdrgui/soapygui/intervalslidergui.h create mode 100644 sdrgui/soapygui/intervalslidergui.ui diff --git a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp index f03411a76..e29b0582b 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp @@ -184,7 +184,7 @@ void SoapySDRInput::getFrequencyRange(uint64_t& min, uint64_t& max) DeviceSoapySDRParams::FrequencySetting freqSettings = channelSettings->m_frequencySettings[0]; SoapySDR::RangeList rangeList = freqSettings.m_ranges; - if (rangeList.size() > 0) // TODO: handle multiple ranges + if (rangeList.size() > 0) { SoapySDR::Range range = rangeList[0]; min = range.minimum(); @@ -203,6 +203,22 @@ void SoapySDRInput::getFrequencyRange(uint64_t& min, uint64_t& max) } } +void SoapySDRInput::getGlobalGainRange(int& min, int& max) +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); + + if (channelSettings) + { + min = channelSettings->m_gainRange.minimum(); + max = channelSettings->m_gainRange.maximum(); + } + else + { + min = 0; + max = 0; + } +} + const std::vector& SoapySDRInput::getAntennas() { const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); @@ -239,6 +255,12 @@ const std::vector& SoapySDRInput::getTun return channelSettings->m_frequencySettings; } +const std::vector& SoapySDRInput::getIndividualGainsRanges() +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); + return channelSettings->m_gainSettings; +} + void SoapySDRInput::init() { applySettings(m_settings, true); @@ -837,6 +859,23 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo } } + if ((m_settings.m_globalGain != settings.m_globalGain) || force) + { + if (dev != 0) + { + try + { + dev->setGain(SOAPY_SDR_RX, requestedChannel, settings.m_globalGain); + qDebug("SoapySDRInput::applySettings: set gain to %d", settings.m_globalGain); + } + catch (const std::exception &ex) + { + qCritical("SoapySDRInput::applySettings: cannot set gain to %d: %s", + settings.m_globalGain, ex.what()); + } + } + } + if (forwardChangeOwnDSP) { int sampleRate = settings.m_devSampleRate/(1<& getAntennas(); const SoapySDR::RangeList& getRateRanges(); const SoapySDR::RangeList& getBandwidthRanges(); int getAntennaIndex(const std::string& antenna); const std::vector& getTunableElements(); + const std::vector& getIndividualGainsRanges(); private: DeviceSourceAPI *m_deviceAPI; diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp b/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp index a3649468f..ba05dcadf 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp @@ -26,6 +26,7 @@ #include "soapygui/intervalrangegui.h" #include "soapygui/stringrangegui.h" #include "soapygui/dynamicitemsettinggui.h" +#include "soapygui/intervalslidergui.h" #include "ui_soapysdrinputgui.h" #include "soapysdrinputgui.h" @@ -42,7 +43,8 @@ SoapySDRInputGui::SoapySDRInputGui(DeviceUISet *deviceUISet, QWidget* parent) : m_lastEngineState(DSPDeviceSourceEngine::StNotStarted), m_antennas(0), m_sampleRateGUI(0), - m_bandwidthGUI(0) + m_bandwidthGUI(0), + m_gainSliderGUI(0) { m_sampleSource = (SoapySDRInput*) m_deviceUISet->m_deviceSourceAPI->getSampleSource(); ui->setupUi(this); @@ -56,6 +58,7 @@ SoapySDRInputGui::SoapySDRInputGui(DeviceUISet *deviceUISet, QWidget* parent) : createRangesControl(&m_sampleRateGUI, m_sampleSource->getRateRanges(), "SR", "S/s"); createRangesControl(&m_bandwidthGUI, m_sampleSource->getBandwidthRanges(), "BW", "Hz"); createTunableElementsControl(m_sampleSource->getTunableElements()); + createGlobalGainControl(); if (m_sampleRateGUI) { connect(m_sampleRateGUI, SIGNAL(valueChanged(double)), this, SLOT(sampleRateChanged(double))); @@ -182,6 +185,21 @@ void SoapySDRInputGui::createTunableElementsControl(const std::vectorgetGlobalGainRange(min, max); + m_gainSliderGUI->setInterval(min, max); + m_gainSliderGUI->setLabel(QString("Global gain")); + m_gainSliderGUI->setUnits(QString("")); + + QVBoxLayout *layout = (QVBoxLayout *) ui->scrollAreaWidgetContents->layout(); + layout->addWidget(m_gainSliderGUI); + + connect(m_gainSliderGUI, SIGNAL(valueChanged(double)), this, SLOT(globalGainChanged(double))); +} + void SoapySDRInputGui::setName(const QString& name) { setObjectName(name); @@ -310,6 +328,12 @@ void SoapySDRInputGui::tunableElementChanged(QString name, double value) sendSettings(); } +void SoapySDRInputGui::globalGainChanged(double gain) +{ + m_settings.m_globalGain = round(gain); + sendSettings(); +} + void SoapySDRInputGui::on_centerFrequency_changed(quint64 value) { m_settings.m_centerFrequency = value * 1000; @@ -403,6 +427,9 @@ void SoapySDRInputGui::displaySettings() if (m_bandwidthGUI) { m_bandwidthGUI->setValue(m_settings.m_bandwidth); } + if (m_gainSliderGUI) { + m_gainSliderGUI->setValue(m_settings.m_globalGain); + } ui->dcOffset->setChecked(m_settings.m_dcBlock); ui->iqImbalance->setChecked(m_settings.m_iqCorrection); diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.h b/plugins/samplesource/soapysdrinput/soapysdrinputgui.h index 0a0233dc8..8678ef617 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.h @@ -30,6 +30,7 @@ class DeviceUISet; class ItemSettingGUI; class StringRangeGUI; class DynamicItemSettingGUI; +class IntervalSliderGUI; namespace Ui { class SoapySDRInputGui; @@ -62,6 +63,7 @@ private: const QString& unit); void createAntennasControl(const std::vector& antennaList); void createTunableElementsControl(const std::vector& tunableElementsList); + void createGlobalGainControl(); Ui::SoapySDRInputGui* ui; @@ -81,6 +83,7 @@ private: ItemSettingGUI *m_sampleRateGUI; ItemSettingGUI *m_bandwidthGUI; std::vector m_tunableElementsGUIs; + IntervalSliderGUI *m_gainSliderGUI; void displaySettings(); void displayTunableElementsControlSettings(); @@ -96,6 +99,7 @@ private slots: void sampleRateChanged(double sampleRate); void bandwidthChanged(double bandwidth); void tunableElementChanged(QString name, double value); + void globalGainChanged(double gain); 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 46f999cc4..2fc6d4232 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp @@ -39,6 +39,7 @@ void SoapySDRInputSettings::resetToDefaults() m_fileRecordName = ""; m_antenna = "NONE"; m_bandwidth = 1000000; + m_globalGain = 0; } QByteArray SoapySDRInputSettings::serialize() const @@ -56,6 +57,7 @@ QByteArray SoapySDRInputSettings::serialize() const s.writeString(9, m_antenna); s.writeU32(10, m_bandwidth); s.writeBlob(11, serializeNamedElementMap(m_tunableElements)); + s.writeS32(12, m_globalGain); return s.final(); } @@ -88,6 +90,7 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data) d.readU32(10, &m_bandwidth, 1000000); d.readBlob(11, &blob); deserializeNamedElementMap(blob, m_tunableElements); + d.readS32(12, &m_globalGain, 0); return true; } diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h index a74f0bc92..a01242f0c 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h @@ -41,6 +41,7 @@ struct SoapySDRInputSettings { QString m_antenna; quint32 m_bandwidth; QMap m_tunableElements; + qint32 m_globalGain; SoapySDRInputSettings(); void resetToDefaults(); diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt index cede779da..2914b29b5 100644 --- a/sdrgui/CMakeLists.txt +++ b/sdrgui/CMakeLists.txt @@ -59,6 +59,7 @@ set(sdrgui_SOURCES soapygui/itemsettinggui.cpp soapygui/stringrangegui.cpp soapygui/dynamicitemsettinggui.cpp + soapygui/intervalslidergui.cpp webapi/webapiadaptergui.cpp ) @@ -122,6 +123,7 @@ set(sdrgui_HEADERS soapygui/itemsettinggui.h soapygui/stringrangegui.h soapygui/dynamicitemsettinggui.h + soapygui/intervalslidergui.h webapi/webapiadaptergui.h ) @@ -153,6 +155,7 @@ set(sdrgui_FORMS gui/loggingdialog.ui soapygui/discreterangegui.ui soapygui/intervalrangegui.ui + soapygui/intervalslidergui.ui ) set(sdrgui_RESOURCES diff --git a/sdrgui/soapygui/intervalslidergui.cpp b/sdrgui/soapygui/intervalslidergui.cpp new file mode 100644 index 000000000..12e71f476 --- /dev/null +++ b/sdrgui/soapygui/intervalslidergui.cpp @@ -0,0 +1,71 @@ +/////////////////////////////////////////////////////////////////////////////////// +// 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 "ui_intervalslidergui.h" +#include "intervalslidergui.h" + +IntervalSliderGUI::IntervalSliderGUI(QWidget* parent) : + QWidget(parent), + ui(new Ui::IntervalSliderGUI), + m_minimum(0), + m_maximum(0) +{ + ui->setupUi(this); +} + +IntervalSliderGUI::~IntervalSliderGUI() +{ + delete ui; +} + +void IntervalSliderGUI::setLabel(const QString& text) +{ + ui->intervalLabel->setText(text); +} + +void IntervalSliderGUI::setUnits(const QString& units) +{ + ui->intervalUnits->setText(units); +} + +void IntervalSliderGUI::setInterval(double minimum, double maximum) +{ + ui->intervalSlider->blockSignals(true); + ui->intervalSlider->setMinimum(minimum); + ui->intervalSlider->setMaximum(maximum); + ui->intervalSlider->blockSignals(false); + m_minimum = minimum; + m_maximum = maximum; +} + +double IntervalSliderGUI::getCurrentValue() +{ + return ui->intervalSlider->value(); +} + +void IntervalSliderGUI::setValue(double value) +{ + ui->intervalSlider->setValue(value); + ui->valueText->setText(QString("%1").arg(ui->intervalSlider->value())); +} + +void IntervalSliderGUI::on_intervalSlider_valueChanged(int value) +{ + ui->valueText->setText(QString("%1").arg(value)); + emit valueChanged(value); +} diff --git a/sdrgui/soapygui/intervalslidergui.h b/sdrgui/soapygui/intervalslidergui.h new file mode 100644 index 000000000..aff65f0c9 --- /dev/null +++ b/sdrgui/soapygui/intervalslidergui.h @@ -0,0 +1,52 @@ +/////////////////////////////////////////////////////////////////////////////////// +// 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRGUI_SOAPYGUI_INTERVALSLIDERGUI_H_ +#define SDRGUI_SOAPYGUI_INTERVALSLIDERGUI_H_ + +#include +#include + +namespace Ui { + class IntervalSliderGUI; +} + +class IntervalSliderGUI : public QWidget +{ + Q_OBJECT +public: + explicit IntervalSliderGUI(QWidget* parent = 0); + virtual ~IntervalSliderGUI(); + + void setLabel(const QString& text); + void setUnits(const QString& units); + void setInterval(double minimum, double maximum); + virtual double getCurrentValue(); + virtual void setValue(double value); + +signals: + void valueChanged(double value); + +private slots: + void on_intervalSlider_valueChanged(int value); + +private: + Ui::IntervalSliderGUI* ui; + double m_minimum; + double m_maximum; +}; + +#endif /* SDRGUI_SOAPYGUI_INTERVALSLIDERGUI_H_ */ diff --git a/sdrgui/soapygui/intervalslidergui.ui b/sdrgui/soapygui/intervalslidergui.ui new file mode 100644 index 000000000..ed34216e1 --- /dev/null +++ b/sdrgui/soapygui/intervalslidergui.ui @@ -0,0 +1,83 @@ + + + IntervalSliderGUI + + + + 0 + 0 + 203 + 30 + + + + + 0 + 0 + + + + + 0 + 30 + + + + Form + + + + + 0 + 0 + 179 + 29 + + + + + + + Label + + + + + + + 1 + + + Qt::Horizontal + + + + + + + + 40 + 0 + + + + 0000 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Unit + + + + + + + + +