mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-08-15 20:22:26 -04:00
SoapySDR support: output: stream ArgInfo GUI
This commit is contained in:
parent
1005d1d4e5
commit
f436479bd7
@ -250,6 +250,31 @@ void SoapySDROutput::initGainSettings(SoapySDROutputSettings& settings)
|
|||||||
updateGains(m_deviceShared.m_device, m_deviceShared.m_channel, settings);
|
updateGains(m_deviceShared.m_device, m_deviceShared.m_channel, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SoapySDR::ArgInfoList& SoapySDROutput::getStreamArgInfoList()
|
||||||
|
{
|
||||||
|
const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel);
|
||||||
|
return channelSettings->m_streamSettingsArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoapySDROutput::initStreamArgSettings(SoapySDROutputSettings& settings)
|
||||||
|
{
|
||||||
|
const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(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 SoapySDROutput::hasDCAutoCorrection()
|
bool SoapySDROutput::hasDCAutoCorrection()
|
||||||
{
|
{
|
||||||
const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel);
|
const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel);
|
||||||
|
@ -133,7 +133,9 @@ public:
|
|||||||
const SoapySDR::RangeList& getBandwidthRanges();
|
const SoapySDR::RangeList& getBandwidthRanges();
|
||||||
const std::vector<DeviceSoapySDRParams::FrequencySetting>& getTunableElements();
|
const std::vector<DeviceSoapySDRParams::FrequencySetting>& getTunableElements();
|
||||||
const std::vector<DeviceSoapySDRParams::GainSetting>& getIndividualGainsRanges();
|
const std::vector<DeviceSoapySDRParams::GainSetting>& getIndividualGainsRanges();
|
||||||
|
const SoapySDR::ArgInfoList& getStreamArgInfoList();
|
||||||
void initGainSettings(SoapySDROutputSettings& settings);
|
void initGainSettings(SoapySDROutputSettings& settings);
|
||||||
|
void initStreamArgSettings(SoapySDROutputSettings& settings);
|
||||||
bool hasDCAutoCorrection();
|
bool hasDCAutoCorrection();
|
||||||
bool hasDCCorrectionValue();
|
bool hasDCCorrectionValue();
|
||||||
bool hasIQAutoCorrection() { return false; } // not in SoapySDR interface
|
bool hasIQAutoCorrection() { return false; } // not in SoapySDR interface
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include "soapygui/dynamicitemsettinggui.h"
|
#include "soapygui/dynamicitemsettinggui.h"
|
||||||
#include "soapygui/intervalslidergui.h"
|
#include "soapygui/intervalslidergui.h"
|
||||||
#include "soapygui/complexfactorgui.h"
|
#include "soapygui/complexfactorgui.h"
|
||||||
|
#include "soapygui/arginfogui.h"
|
||||||
|
#include "soapygui/dynamicargsettinggui.h"
|
||||||
|
|
||||||
#include "soapysdroutputgui.h"
|
#include "soapysdroutputgui.h"
|
||||||
|
|
||||||
@ -67,7 +69,9 @@ SoapySDROutputGui::SoapySDROutputGui(DeviceUISet *deviceUISet, QWidget* parent)
|
|||||||
createTunableElementsControl(m_sampleSink->getTunableElements());
|
createTunableElementsControl(m_sampleSink->getTunableElements());
|
||||||
createGlobalGainControl();
|
createGlobalGainControl();
|
||||||
createIndividualGainsControl(m_sampleSink->getIndividualGainsRanges());
|
createIndividualGainsControl(m_sampleSink->getIndividualGainsRanges());
|
||||||
|
createStreamArgumentsControl(m_sampleSink->getStreamArgInfoList());
|
||||||
m_sampleSink->initGainSettings(m_settings);
|
m_sampleSink->initGainSettings(m_settings);
|
||||||
|
m_sampleSink->initStreamArgSettings(m_settings);
|
||||||
|
|
||||||
if (m_sampleRateGUI) {
|
if (m_sampleRateGUI) {
|
||||||
connect(m_sampleRateGUI, SIGNAL(valueChanged(double)), this, SLOT(sampleRateChanged(double)));
|
connect(m_sampleRateGUI, SIGNAL(valueChanged(double)), this, SLOT(sampleRateChanged(double)));
|
||||||
@ -303,6 +307,86 @@ void SoapySDROutputGui::createCorrectionsControl()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoapySDROutputGui::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 SoapySDROutputGui::setName(const QString& name)
|
void SoapySDROutputGui::setName(const QString& name)
|
||||||
{
|
{
|
||||||
setObjectName(name);
|
setObjectName(name);
|
||||||
@ -509,6 +593,12 @@ void SoapySDROutputGui::iqCorrectionArgumentChanged(double value)
|
|||||||
sendSettings();
|
sendSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoapySDROutputGui::streamArgChanged(QString itemName, QVariant value)
|
||||||
|
{
|
||||||
|
m_settings.m_streamArgSettings[itemName] = value;
|
||||||
|
sendSettings();
|
||||||
|
}
|
||||||
|
|
||||||
void SoapySDROutputGui::on_centerFrequency_changed(quint64 value)
|
void SoapySDROutputGui::on_centerFrequency_changed(quint64 value)
|
||||||
{
|
{
|
||||||
m_settings.m_centerFrequency = value * 1000;
|
m_settings.m_centerFrequency = value * 1000;
|
||||||
@ -585,6 +675,7 @@ void SoapySDROutputGui::displaySettings()
|
|||||||
displayTunableElementsControlSettings();
|
displayTunableElementsControlSettings();
|
||||||
displayIndividualGainsControlSettings();
|
displayIndividualGainsControlSettings();
|
||||||
displayCorrectionsSettings();
|
displayCorrectionsSettings();
|
||||||
|
displayStreamArgsSettings();
|
||||||
|
|
||||||
blockApplySettings(false);
|
blockApplySettings(false);
|
||||||
}
|
}
|
||||||
@ -640,6 +731,20 @@ void SoapySDROutputGui::displayCorrectionsSettings()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoapySDROutputGui::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 SoapySDROutputGui::sendSettings()
|
void SoapySDROutputGui::sendSettings()
|
||||||
{
|
{
|
||||||
if (!m_updateTimer.isActive()) {
|
if (!m_updateTimer.isActive()) {
|
||||||
|
@ -31,6 +31,7 @@ class DeviceUISet;
|
|||||||
class ItemSettingGUI;
|
class ItemSettingGUI;
|
||||||
class StringRangeGUI;
|
class StringRangeGUI;
|
||||||
class DynamicItemSettingGUI;
|
class DynamicItemSettingGUI;
|
||||||
|
class DynamicArgSettingGUI;
|
||||||
class IntervalSliderGUI;
|
class IntervalSliderGUI;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class ComplexFactorGUI;
|
class ComplexFactorGUI;
|
||||||
@ -69,6 +70,7 @@ private:
|
|||||||
void createGlobalGainControl();
|
void createGlobalGainControl();
|
||||||
void createIndividualGainsControl(const std::vector<DeviceSoapySDRParams::GainSetting>& individualGainsList);
|
void createIndividualGainsControl(const std::vector<DeviceSoapySDRParams::GainSetting>& individualGainsList);
|
||||||
void createCorrectionsControl();
|
void createCorrectionsControl();
|
||||||
|
void createStreamArgumentsControl(const SoapySDR::ArgInfoList& argInfoList);
|
||||||
|
|
||||||
Ui::SoapySDROutputGui* ui;
|
Ui::SoapySDROutputGui* ui;
|
||||||
|
|
||||||
@ -95,12 +97,14 @@ private:
|
|||||||
ComplexFactorGUI *m_iqCorrectionGUI;
|
ComplexFactorGUI *m_iqCorrectionGUI;
|
||||||
QCheckBox *m_autoDCCorrection;
|
QCheckBox *m_autoDCCorrection;
|
||||||
QCheckBox *m_autoIQCorrection;
|
QCheckBox *m_autoIQCorrection;
|
||||||
|
std::vector<DynamicArgSettingGUI*> m_streamArgsGUIs;
|
||||||
|
|
||||||
void blockApplySettings(bool block) { m_doApplySettings = !block; }
|
void blockApplySettings(bool block) { m_doApplySettings = !block; }
|
||||||
void displaySettings();
|
void displaySettings();
|
||||||
void displayTunableElementsControlSettings();
|
void displayTunableElementsControlSettings();
|
||||||
void displayIndividualGainsControlSettings();
|
void displayIndividualGainsControlSettings();
|
||||||
void displayCorrectionsSettings();
|
void displayCorrectionsSettings();
|
||||||
|
void displayStreamArgsSettings();
|
||||||
void sendSettings();
|
void sendSettings();
|
||||||
void updateSampleRateAndFrequency();
|
void updateSampleRateAndFrequency();
|
||||||
void updateFrequencyLimits();
|
void updateFrequencyLimits();
|
||||||
@ -122,6 +126,7 @@ private slots:
|
|||||||
void dcCorrectionArgumentChanged(double value);
|
void dcCorrectionArgumentChanged(double value);
|
||||||
void iqCorrectionModuleChanged(double value);
|
void iqCorrectionModuleChanged(double value);
|
||||||
void iqCorrectionArgumentChanged(double value);
|
void iqCorrectionArgumentChanged(double value);
|
||||||
|
void streamArgChanged(QString itemName, QVariant value);
|
||||||
|
|
||||||
void on_centerFrequency_changed(quint64 value);
|
void on_centerFrequency_changed(quint64 value);
|
||||||
void on_LOppm_valueChanged(int value);
|
void on_LOppm_valueChanged(int value);
|
||||||
|
@ -65,6 +65,7 @@ QByteArray SoapySDROutputSettings::serialize() const
|
|||||||
s.writeDouble(18, m_dcCorrection.imag());
|
s.writeDouble(18, m_dcCorrection.imag());
|
||||||
s.writeDouble(19, m_iqCorrection.real());
|
s.writeDouble(19, m_iqCorrection.real());
|
||||||
s.writeDouble(20, m_iqCorrection.imag());
|
s.writeDouble(20, m_iqCorrection.imag());
|
||||||
|
s.writeBlob(21, serializeArgumentMap(m_streamArgSettings));
|
||||||
|
|
||||||
return s.final();
|
return s.final();
|
||||||
}
|
}
|
||||||
@ -105,6 +106,8 @@ bool SoapySDROutputSettings::deserialize(const QByteArray& data)
|
|||||||
d.readDouble(19, &realval, 0);
|
d.readDouble(19, &realval, 0);
|
||||||
d.readDouble(20, &imagval, 0);
|
d.readDouble(20, &imagval, 0);
|
||||||
m_iqCorrection = std::complex<double>{realval, imagval};
|
m_iqCorrection = std::complex<double>{realval, imagval};
|
||||||
|
d.readBlob(21, &blob);
|
||||||
|
deserializeArgumentMap(blob, m_streamArgSettings);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -131,3 +134,21 @@ void SoapySDROutputSettings::deserializeNamedElementMap(const QByteArray& data,
|
|||||||
(*stream) >> map;
|
(*stream) >> map;
|
||||||
delete stream;
|
delete stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray SoapySDROutputSettings::serializeArgumentMap(const QMap<QString, QVariant>& map) const
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QDataStream *stream = new QDataStream(&data, QIODevice::WriteOnly);
|
||||||
|
(*stream) << map;
|
||||||
|
delete stream;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoapySDROutputSettings::deserializeArgumentMap(const QByteArray& data, QMap<QString, QVariant>& map)
|
||||||
|
{
|
||||||
|
QDataStream *stream = new QDataStream(data);
|
||||||
|
(*stream) >> map;
|
||||||
|
delete stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#define PLUGINS_SAMPLESINK_SOAPYSDROUTPUT_SOAPYSDROUTPUTSETTINGS_H_
|
#define PLUGINS_SAMPLESINK_SOAPYSDROUTPUT_SOAPYSDROUTPUTSETTINGS_H_
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
#include <QVariant>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
|
||||||
struct SoapySDROutputSettings {
|
struct SoapySDROutputSettings {
|
||||||
@ -37,6 +38,7 @@ struct SoapySDROutputSettings {
|
|||||||
bool m_autoIQCorrection;
|
bool m_autoIQCorrection;
|
||||||
std::complex<double> m_dcCorrection;
|
std::complex<double> m_dcCorrection;
|
||||||
std::complex<double> m_iqCorrection;
|
std::complex<double> m_iqCorrection;
|
||||||
|
QMap<QString, QVariant> m_streamArgSettings;
|
||||||
|
|
||||||
SoapySDROutputSettings();
|
SoapySDROutputSettings();
|
||||||
void resetToDefaults();
|
void resetToDefaults();
|
||||||
@ -46,6 +48,9 @@ struct SoapySDROutputSettings {
|
|||||||
private:
|
private:
|
||||||
QByteArray serializeNamedElementMap(const QMap<QString, double>& map) const;
|
QByteArray serializeNamedElementMap(const QMap<QString, double>& map) const;
|
||||||
void deserializeNamedElementMap(const QByteArray& data, QMap<QString, double>& map);
|
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_SAMPLESINK_SOAPYSDROUTPUT_SOAPYSDROUTPUTSETTINGS_H_ */
|
#endif /* PLUGINS_SAMPLESINK_SOAPYSDROUTPUT_SOAPYSDROUTPUTSETTINGS_H_ */
|
||||||
|
@ -156,7 +156,7 @@ QByteArray SoapySDRInputSettings::serializeArgumentMap(const QMap<QString, QVari
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deserializeArgumentMap(const QByteArray& data, QMap<QString, QVariant>& map)
|
void SoapySDRInputSettings::deserializeArgumentMap(const QByteArray& data, QMap<QString, QVariant>& map)
|
||||||
{
|
{
|
||||||
QDataStream *stream = new QDataStream(data);
|
QDataStream *stream = new QDataStream(data);
|
||||||
(*stream) >> map;
|
(*stream) >> map;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user