diff --git a/devices/soapysdr/devicesoapysdrparams.cpp b/devices/soapysdr/devicesoapysdrparams.cpp index 2caa0ba9e..0e5d25c03 100644 --- a/devices/soapysdr/devicesoapysdrparams.cpp +++ b/devices/soapysdr/devicesoapysdrparams.cpp @@ -120,11 +120,9 @@ void DeviceSoapySDRParams::fillChannelParams(std::vector& chann channelSettings.back().m_frequencySettingsArgs = m_device->getFrequencyArgsInfo(direction, ichan); // sample rates - channelSettings.back().m_ratesRanges = m_device->getSampleRateRange(direction, ichan); // bandwidths - channelSettings.back().m_bandwidthsRanges = m_device->getBandwidthRange(direction, ichan); } diff --git a/plugins/samplesink/soapysdroutput/soapysdroutput.cpp b/plugins/samplesink/soapysdroutput/soapysdroutput.cpp index b861c2348..78d97fc1c 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutput.cpp +++ b/plugins/samplesink/soapysdroutput/soapysdroutput.cpp @@ -189,6 +189,12 @@ const SoapySDR::RangeList& SoapySDROutput::getRateRanges() return channelSettings->m_ratesRanges; } +const std::vector& SoapySDROutput::getAntennas() +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel); + return channelSettings->m_antennas; +} + void SoapySDROutput::init() { applySettings(m_settings, true); diff --git a/plugins/samplesink/soapysdroutput/soapysdroutput.h b/plugins/samplesink/soapysdroutput/soapysdroutput.h index b9ec34c63..d954e1e35 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutput.h +++ b/plugins/samplesink/soapysdroutput/soapysdroutput.h @@ -101,6 +101,7 @@ public: void getFrequencyRange(uint64_t& min, uint64_t& max); const SoapySDR::RangeList& getRateRanges(); + const std::vector& getAntennas(); private: DeviceSinkAPI *m_deviceAPI; diff --git a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp index 38adbe497..30b5b7d23 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp @@ -209,6 +209,24 @@ const SoapySDR::RangeList& SoapySDRInput::getRateRanges() return channelSettings->m_ratesRanges; } +const std::vector& SoapySDRInput::getAntennas() +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); + return channelSettings->m_antennas; +} + +int SoapySDRInput::getAntennaIndex(const std::string& antenna) +{ + const std::vector& antennaList = getAntennas(); + std::vector::const_iterator it = std::find(antennaList.begin(), antennaList.end(), antenna); + + if (it == antennaList.end()) { + return -1; + } else { + return it - antennaList.begin(); + } +} + void SoapySDRInput::init() { applySettings(m_settings, true); @@ -745,6 +763,23 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo } } + if ((m_settings.m_antenna != settings.m_antenna) || force) + { + if (dev != 0) + { + try + { + dev->setAntenna(SOAPY_SDR_RX, requestedChannel, settings.m_antenna.toStdString()); + qDebug("SoapySDRInput::applySettings: set antenna to %s", settings.m_antenna.toStdString().c_str()); + } + catch (const std::exception &ex) + { + qCritical("SoapySDRInput::applySettings: cannot set antenna to %s: %s", + settings.m_antenna.toStdString().c_str(), ex.what()); + } + } + } + if (forwardChangeOwnDSP) { int sampleRate = settings.m_devSampleRate/(1<& getAntennas(); + int getAntennaIndex(const std::string& antenna); private: DeviceSourceAPI *m_deviceAPI; diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp b/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp index e26547931..7f749a4e9 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp @@ -49,6 +49,7 @@ SoapySDRInputGui::SoapySDRInputGui(DeviceUISet *deviceUISet, QWidget* parent) : ui->centerFrequency->setValueRange(7, f_min/1000, f_max/1000); createRangesControl(m_sampleSource->getRateRanges(), "SR", "kS/s"); + createAntennasControl(m_sampleSource->getAntennas()); connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware())); connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus())); @@ -92,7 +93,7 @@ void SoapySDRInputGui::createRangesControl(const SoapySDR::RangeList& rangeList, if (rangeDiscrete) { - DiscreteRangeGUI *rangeGUI = new DiscreteRangeGUI(ui->scrollAreaWidgetContents); + DiscreteRangeGUI *rangeGUI = new DiscreteRangeGUI(this); rangeGUI->setLabel(text); rangeGUI->setUnits(unit); @@ -101,6 +102,9 @@ void SoapySDRInputGui::createRangesControl(const SoapySDR::RangeList& rangeList, } m_sampleRateGUI = rangeGUI; + QVBoxLayout *layout = (QVBoxLayout *) ui->scrollAreaWidgetContents->layout(); + layout->addWidget(rangeGUI); + connect(m_sampleRateGUI, SIGNAL(valueChanged(double)), this, SLOT(sampleRateChanged(double))); // QHBoxLayout *layout = new QHBoxLayout(); // QLabel *rangeLabel = new QLabel(); @@ -140,10 +144,29 @@ void SoapySDRInputGui::createRangesControl(const SoapySDR::RangeList& rangeList, rangeGUI->reset(); m_sampleRateGUI = rangeGUI; + QVBoxLayout *layout = (QVBoxLayout *) ui->scrollAreaWidgetContents->layout(); + layout->addWidget(rangeGUI); + connect(m_sampleRateGUI, SIGNAL(valueChanged(double)), this, SLOT(sampleRateChanged(double))); } } +void SoapySDRInputGui::createAntennasControl(const std::vector& antennaList) +{ + m_antennas = new StringRangeGUI(this); + m_antennas->setLabel(QString("Antenna")); + m_antennas->setUnits(QString("Port")); + + for (const auto &it : antennaList) { + m_antennas->addItem(QString(it.c_str()), it); + } + + QVBoxLayout *layout = (QVBoxLayout *) ui->scrollAreaWidgetContents->layout(); + layout->addWidget(m_antennas); + + connect(m_antennas, SIGNAL(valueChanged()), this, SLOT(antennasChanged())); +} + void SoapySDRInputGui::setName(const QString& name) { setObjectName(name); @@ -252,6 +275,14 @@ void SoapySDRInputGui::sampleRateChanged(double sampleRate) sendSettings(); } +void SoapySDRInputGui::antennasChanged() +{ + const std::string& antennaStr = m_antennas->getCurrentValue(); + m_settings.m_antenna = QString(antennaStr.c_str()); + + sendSettings(); +} + void SoapySDRInputGui::on_centerFrequency_changed(quint64 value) { m_settings.m_centerFrequency = value * 1000; @@ -346,6 +377,8 @@ void SoapySDRInputGui::displaySettings() ui->LOppm->setValue(m_settings.m_LOppmTenths); ui->LOppmText->setText(QString("%1").arg(QString::number(m_settings.m_LOppmTenths/10.0, 'f', 1))); + m_antennas->setValue(m_settings.m_antenna.toStdString()); + blockApplySettings(false); } diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.h b/plugins/samplesource/soapysdrinput/soapysdrinputgui.h index bb2b06511..8fbe09013 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.h @@ -17,12 +17,13 @@ #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; @@ -53,6 +54,8 @@ public: private: void createRangesControl(const SoapySDR::RangeList& rangeList, const QString& text, const QString& unit); + void createAntennasControl(const std::vector& antennaList); + Ui::SoapySDRInputGui* ui; DeviceUISet* m_deviceUISet; @@ -68,6 +71,7 @@ private: MessageQueue m_inputMessageQueue; ItemSettingGUI *m_sampleRateGUI; + StringRangeGUI *m_antennas; void displaySettings(); void sendSettings(); @@ -81,6 +85,7 @@ private slots: void on_centerFrequency_changed(quint64 value); void on_LOppm_valueChanged(int value); void sampleRateChanged(double sampleRate); + void antennasChanged(); void on_dcOffset_toggled(bool checked); void on_iqImbalance_toggled(bool checked); void on_decim_currentIndexChanged(int index); diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.ui b/plugins/samplesource/soapysdrinput/soapysdrinputgui.ui index b5e295eef..c6d29c657 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.ui +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.ui @@ -382,8 +382,8 @@ 0 0 - 304 - 120 + 318 + 51 @@ -402,143 +402,6 @@ 0 - - - - - - Data1 - - - - - - - - 0 - - - - - 1 - - - - - 2 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Kiki - - - - - - - Qt::Horizontal - - - - - - - 0.0 - - - - - - - - - - - TextLabel - - - - - - - ... - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Tata - - - - - - - - - - - Zozo - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp index ba8e75e2a..901c7f9dc 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp @@ -35,6 +35,7 @@ void SoapySDRInputSettings::resetToDefaults() m_transverterMode = false; m_transverterDeltaFrequency = 0; m_fileRecordName = ""; + m_antenna = "NONE"; } QByteArray SoapySDRInputSettings::serialize() const @@ -49,6 +50,7 @@ QByteArray SoapySDRInputSettings::serialize() const s.writeS32(6, m_LOppmTenths); s.writeBool(7, m_transverterMode); s.writeS64(8, m_transverterDeltaFrequency); + s.writeString(9, m_antenna); return s.final(); } @@ -76,6 +78,7 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data) d.readS32(6, &m_LOppmTenths); d.readBool(7, &m_transverterMode, false); d.readS64(8, &m_transverterDeltaFrequency, 0); + d.readString(9, &m_antenna, "NONE"); return true; } diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h index 53c967b03..8991c8ec1 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h @@ -37,6 +37,7 @@ struct SoapySDRInputSettings { bool m_transverterMode; qint64 m_transverterDeltaFrequency; QString m_fileRecordName; + QString m_antenna; SoapySDRInputSettings(); void resetToDefaults(); diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt index 1130a0a47..709164adf 100644 --- a/sdrgui/CMakeLists.txt +++ b/sdrgui/CMakeLists.txt @@ -57,6 +57,7 @@ set(sdrgui_SOURCES soapygui/discreterangegui.cpp soapygui/intervalrangegui.cpp soapygui/itemsettinggui.cpp + soapygui/stringrangegui.cpp webapi/webapiadaptergui.cpp ) @@ -118,6 +119,7 @@ set(sdrgui_HEADERS soapygui/discreterangegui.h soapygui/intervalrangegui.h soapygui/itemsettinggui.h + soapygui/stringrangegui.h webapi/webapiadaptergui.h ) diff --git a/sdrgui/soapygui/stringrangegui.cpp b/sdrgui/soapygui/stringrangegui.cpp new file mode 100644 index 000000000..2cf3cb011 --- /dev/null +++ b/sdrgui/soapygui/stringrangegui.cpp @@ -0,0 +1,78 @@ +/////////////////////////////////////////////////////////////////////////////////// +// 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 "ui_discreterangegui.h" + +#include "stringrangegui.h" + +StringRangeGUI::StringRangeGUI(QWidget* parent) : + QWidget(parent), + ui(new Ui::DiscreteRangeGUI) +{ + ui->setupUi(this); +} + +StringRangeGUI::~StringRangeGUI() +{ + delete ui; +} + +void StringRangeGUI::setLabel(const QString& text) +{ + ui->rangeLabel->setText(text); +} + +void StringRangeGUI::setUnits(const QString& units) +{ + ui->rangeUnits->setText(units); +} + +void StringRangeGUI::addItem(const QString& itemStr, const std::string& itemValue) +{ + ui->rangeCombo->blockSignals(true); + ui->rangeCombo->addItem(itemStr); + itemValues.push_back(itemValue); + ui->rangeCombo->blockSignals(false); +} + +const std::string& StringRangeGUI::getCurrentValue() +{ + return itemValues[ui->rangeCombo->currentIndex()]; +} + +void StringRangeGUI::setValue(const std::string& value) +{ + int index = 0; + + for (const auto &it : itemValues) + { + if (it >= value) + { + ui->rangeCombo->blockSignals(true); + ui->rangeCombo->setCurrentIndex(index); + ui->rangeCombo->blockSignals(false); + break; + } + + index++; + } +} + +void StringRangeGUI::on_rangeCombo_currentIndexChanged(int index __attribute__((unused))) +{ + emit valueChanged(); +} + diff --git a/sdrgui/soapygui/stringrangegui.h b/sdrgui/soapygui/stringrangegui.h new file mode 100644 index 000000000..994fcf378 --- /dev/null +++ b/sdrgui/soapygui/stringrangegui.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_STRINGRANGEGUI_H_ +#define SDRGUI_SOAPYGUI_STRINGRANGEGUI_H_ + +#include + +namespace Ui { + class DiscreteRangeGUI; +} + +class StringRangeGUI : public QWidget +{ + Q_OBJECT +public: + explicit StringRangeGUI(QWidget* parent = 0); + virtual ~StringRangeGUI(); + + void setLabel(const QString& text); + void setUnits(const QString& units); + void addItem(const QString& itemStr, const std::string& itemValue); + const std::string& getCurrentValue(); + void setValue(const std::string& value); + +signals: + void valueChanged(); + +private slots: + void on_rangeCombo_currentIndexChanged(int index); + +private: + Ui::DiscreteRangeGUI* ui; + std::vector itemValues; +}; + + + +#endif /* SDRGUI_SOAPYGUI_STRINGRANGEGUI_H_ */