1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-06-01 21:54:55 -04:00

SoapySDR support: input: stream ArgInfo GUI

This commit is contained in:
f4exb
2018-11-11 02:30:10 +01:00
parent 3c9d1a3637
commit 1005d1d4e5
12 changed files with 353 additions and 5 deletions
@@ -269,6 +269,12 @@ const std::vector<DeviceSoapySDRParams::GainSetting>& SoapySDRInput::getIndividu
return channelSettings->m_gainSettings;
}
const SoapySDR::ArgInfoList& SoapySDRInput::getStreamArgInfoList()
{
const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel);
return channelSettings->m_streamSettingsArgs;
}
void SoapySDRInput::initGainSettings(SoapySDRInputSettings& settings)
{
const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel);
@@ -282,6 +288,25 @@ void SoapySDRInput::initGainSettings(SoapySDRInputSettings& settings)
updateGains(m_deviceShared.m_device, m_deviceShared.m_channel, settings);
}
void SoapySDRInput::initStreamArgSettings(SoapySDRInputSettings& settings)
{
const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel);
settings.m_streamArgSettings.clear();
for (const auto &it : channelSettings->m_streamSettingsArgs)
{
if (it.type == SoapySDR::ArgInfo::BOOL) {
settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(it.value == "true");
} else if (it.type == SoapySDR::ArgInfo::INT) {
settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(atoi(it.value.c_str()));
} else if (it.type == SoapySDR::ArgInfo::FLOAT) {
settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(atof(it.value.c_str()));
} else if (it.type == SoapySDR::ArgInfo::STRING) {
settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(it.value.c_str());
}
}
}
bool SoapySDRInput::hasDCAutoCorrection()
{
const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel);
@@ -155,7 +155,9 @@ public:
int getAntennaIndex(const std::string& antenna);
const std::vector<DeviceSoapySDRParams::FrequencySetting>& getTunableElements();
const std::vector<DeviceSoapySDRParams::GainSetting>& getIndividualGainsRanges();
const SoapySDR::ArgInfoList& getStreamArgInfoList();
void initGainSettings(SoapySDRInputSettings& settings);
void initStreamArgSettings(SoapySDRInputSettings& settings);
bool hasDCAutoCorrection();
bool hasDCCorrectionValue();
bool hasIQAutoCorrection() { return false; } // not in SoapySDR interface
@@ -29,6 +29,8 @@
#include "soapygui/dynamicitemsettinggui.h"
#include "soapygui/intervalslidergui.h"
#include "soapygui/complexfactorgui.h"
#include "soapygui/arginfogui.h"
#include "soapygui/dynamicargsettinggui.h"
#include "ui_soapysdrinputgui.h"
#include "soapysdrinputgui.h"
@@ -68,7 +70,9 @@ SoapySDRInputGui::SoapySDRInputGui(DeviceUISet *deviceUISet, QWidget* parent) :
createTunableElementsControl(m_sampleSource->getTunableElements());
createGlobalGainControl();
createIndividualGainsControl(m_sampleSource->getIndividualGainsRanges());
createStreamArgumentsControl(m_sampleSource->getStreamArgInfoList());
m_sampleSource->initGainSettings(m_settings);
m_sampleSource->initStreamArgSettings(m_settings);
if (m_sampleRateGUI) {
connect(m_sampleRateGUI, SIGNAL(valueChanged(double)), this, SLOT(sampleRateChanged(double)));
@@ -306,6 +310,86 @@ void SoapySDRInputGui::createCorrectionsControl()
}
}
void SoapySDRInputGui::createStreamArgumentsControl(const SoapySDR::ArgInfoList& argInfoList)
{
if (argInfoList.size() == 0) { // return early if list is empty
return;
}
QVBoxLayout *layout = (QVBoxLayout *) ui->scrollAreaWidgetContents->layout();
QFrame *line = new QFrame(this);
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
layout->addWidget(line);
std::vector<SoapySDR::ArgInfo>::const_iterator it = argInfoList.begin();
for (; it != argInfoList.end(); ++it)
{
ArgInfoGUI::ArgInfoValueType valueType;
ArgInfoGUI *argGUI;
if (it->type == SoapySDR::ArgInfo::BOOL) {
valueType = ArgInfoGUI::ArgInfoValueBool;
} else if (it->type == SoapySDR::ArgInfo::INT) {
valueType = ArgInfoGUI::ArgInfoValueInt;
} else if (it->type == SoapySDR::ArgInfo::FLOAT) {
valueType = ArgInfoGUI::ArgInfoValueFloat;
} else if (it->type == SoapySDR::ArgInfo::STRING) {
valueType = ArgInfoGUI::ArgInfoValueString;
} else {
continue;
}
if (valueType == ArgInfoGUI::ArgInfoValueBool)
{
argGUI = new ArgInfoGUI(ArgInfoGUI::ArgInfoBinary, ArgInfoGUI::ArgInfoValueBool, this);
}
else if (it->options.size() == 0)
{
argGUI = new ArgInfoGUI(ArgInfoGUI::ArgInfoContinuous, valueType, this);
}
else
{
argGUI = new ArgInfoGUI(ArgInfoGUI::ArgInfoDiscrete, valueType, this);
std::vector<std::string>::const_iterator optionIt = it->options.begin();
std::vector<std::string>::const_iterator optionNameIt = it->optionNames.begin();
for (int i = 0; optionIt != it->options.end(); ++optionIt, i++)
{
QString name(optionNameIt == it->optionNames.end() ? optionIt->c_str() : optionNameIt->c_str());
++optionNameIt;
if (valueType == ArgInfoGUI::ArgInfoValueInt) {
argGUI->addIntValue(name, atoi(optionIt->c_str()));
} else if (valueType == ArgInfoGUI::ArgInfoValueFloat) {
argGUI->addFloatValue(name, atof(optionIt->c_str()));
} else if (valueType == ArgInfoGUI::ArgInfoValueString) {
argGUI->addStringValue(name, QString(optionIt->c_str()));
}
}
}
if ((it->range.minimum() != 0) || (it->range.maximum() != 0)) {
argGUI->setRange(it->range.minimum(), it->range.maximum());
}
argGUI->setLabel(QString(it->name.size() == 0 ? it->key.c_str() : it->name.c_str()));
argGUI->setUnits(QString(it->units.c_str()));
if (it->description.size() != 0) {
argGUI->setToolTip(QString(it->description.c_str()));
}
layout->addWidget(argGUI);
DynamicArgSettingGUI *gui = new DynamicArgSettingGUI(argGUI, QString(it->key.c_str()));
m_streamArgsGUIs.push_back(gui);
connect(gui, SIGNAL(valueChanged(QString, value)), this, SLOT(streamArgChanged(QString, QVariant)));
}
}
void SoapySDRInputGui::setName(const QString& name)
{
setObjectName(name);
@@ -512,6 +596,12 @@ void SoapySDRInputGui::iqCorrectionArgumentChanged(double value)
sendSettings();
}
void SoapySDRInputGui::streamArgChanged(QString itemName, QVariant value)
{
m_settings.m_streamArgSettings[itemName] = value;
sendSettings();
}
void SoapySDRInputGui::on_centerFrequency_changed(quint64 value)
{
m_settings.m_centerFrequency = value * 1000;
@@ -631,6 +721,7 @@ void SoapySDRInputGui::displaySettings()
displayTunableElementsControlSettings();
displayIndividualGainsControlSettings();
displayCorrectionsSettings();
displayStreamArgsSettings();
blockApplySettings(false);
}
@@ -686,6 +777,20 @@ void SoapySDRInputGui::displayCorrectionsSettings()
}
}
void SoapySDRInputGui::displayStreamArgsSettings()
{
for (const auto &it : m_streamArgsGUIs)
{
QMap<QString, QVariant>::iterator elIt = m_settings.m_streamArgSettings.find(it->getName());
if (elIt != m_settings.m_streamArgSettings.end())
{
it->setValue(*elIt);
*elIt = it->getValue();
}
}
}
void SoapySDRInputGui::sendSettings()
{
if (!m_updateTimer.isActive()) {
@@ -29,6 +29,7 @@ class DeviceUISet;
class ItemSettingGUI;
class StringRangeGUI;
class DynamicItemSettingGUI;
class DynamicArgSettingGUI;
class IntervalSliderGUI;
class QCheckBox;
class ComplexFactorGUI;
@@ -67,6 +68,7 @@ private:
void createGlobalGainControl();
void createIndividualGainsControl(const std::vector<DeviceSoapySDRParams::GainSetting>& individualGainsList);
void createCorrectionsControl();
void createStreamArgumentsControl(const SoapySDR::ArgInfoList& argInfoList);
Ui::SoapySDRInputGui* ui;
@@ -93,11 +95,13 @@ private:
ComplexFactorGUI *m_iqCorrectionGUI;
QCheckBox *m_autoDCCorrection;
QCheckBox *m_autoIQCorrection;
std::vector<DynamicArgSettingGUI*> m_streamArgsGUIs;
void displaySettings();
void displayTunableElementsControlSettings();
void displayIndividualGainsControlSettings();
void displayCorrectionsSettings();
void displayStreamArgsSettings();
void sendSettings();
void updateSampleRateAndFrequency();
void updateFrequencyLimits();
@@ -119,6 +123,7 @@ private slots:
void dcCorrectionArgumentChanged(double value);
void iqCorrectionModuleChanged(double value);
void iqCorrectionArgumentChanged(double value);
void streamArgChanged(QString itemName, QVariant value);
void on_centerFrequency_changed(quint64 value);
void on_LOppm_valueChanged(int value);
@@ -71,6 +71,7 @@ QByteArray SoapySDRInputSettings::serialize() const
s.writeDouble(18, m_dcCorrection.imag());
s.writeDouble(19, m_iqCorrection.real());
s.writeDouble(20, m_iqCorrection.imag());
s.writeBlob(21, serializeArgumentMap(m_streamArgSettings));
return s.final();
}
@@ -116,6 +117,8 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data)
d.readDouble(19, &realval, 0);
d.readDouble(20, &imagval, 0);
m_iqCorrection = std::complex<double>{realval, imagval};
d.readBlob(21, &blob);
deserializeArgumentMap(blob, m_streamArgSettings);
return true;
}
@@ -142,3 +145,21 @@ void SoapySDRInputSettings::deserializeNamedElementMap(const QByteArray& data, Q
(*stream) >> map;
delete stream;
}
QByteArray SoapySDRInputSettings::serializeArgumentMap(const QMap<QString, QVariant>& map) const
{
QByteArray data;
QDataStream *stream = new QDataStream(&data, QIODevice::WriteOnly);
(*stream) << map;
delete stream;
return data;
}
void deserializeArgumentMap(const QByteArray& data, QMap<QString, QVariant>& map)
{
QDataStream *stream = new QDataStream(data);
(*stream) >> map;
delete stream;
}
@@ -19,6 +19,7 @@
#include <QtGlobal>
#include <QString>
#include <QVariant>
#include <QMap>
struct SoapySDRInputSettings {
@@ -48,6 +49,7 @@ struct SoapySDRInputSettings {
bool m_autoIQCorrection;
std::complex<double> m_dcCorrection;
std::complex<double> m_iqCorrection;
QMap<QString, QVariant> m_streamArgSettings;
SoapySDRInputSettings();
void resetToDefaults();
@@ -57,6 +59,8 @@ struct SoapySDRInputSettings {
private:
QByteArray serializeNamedElementMap(const QMap<QString, double>& map) const;
void deserializeNamedElementMap(const QByteArray& data, QMap<QString, double>& map);
QByteArray serializeArgumentMap(const QMap<QString, QVariant>& map) const;
void deserializeArgumentMap(const QByteArray& data, QMap<QString, QVariant>& map);
};
#endif /* PLUGINS_SAMPLESOURCE_SOAPYSDRINPUT_SOAPYSDRINPUTSETTINGS_H_ */