mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 13:00: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); | ||||
| } | ||||
| 
 | ||||
| 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() | ||||
| { | ||||
|     const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel); | ||||
|  | ||||
| @ -133,7 +133,9 @@ public: | ||||
|     const SoapySDR::RangeList& getBandwidthRanges(); | ||||
|     const std::vector<DeviceSoapySDRParams::FrequencySetting>& getTunableElements(); | ||||
|     const std::vector<DeviceSoapySDRParams::GainSetting>& getIndividualGainsRanges(); | ||||
|     const SoapySDR::ArgInfoList& getStreamArgInfoList(); | ||||
|     void initGainSettings(SoapySDROutputSettings& settings); | ||||
|     void initStreamArgSettings(SoapySDROutputSettings& settings); | ||||
|     bool hasDCAutoCorrection(); | ||||
|     bool hasDCCorrectionValue(); | ||||
|     bool hasIQAutoCorrection() { return false; } // not in SoapySDR interface
 | ||||
|  | ||||
| @ -30,6 +30,8 @@ | ||||
| #include "soapygui/dynamicitemsettinggui.h" | ||||
| #include "soapygui/intervalslidergui.h" | ||||
| #include "soapygui/complexfactorgui.h" | ||||
| #include "soapygui/arginfogui.h" | ||||
| #include "soapygui/dynamicargsettinggui.h" | ||||
| 
 | ||||
| #include "soapysdroutputgui.h" | ||||
| 
 | ||||
| @ -67,7 +69,9 @@ SoapySDROutputGui::SoapySDROutputGui(DeviceUISet *deviceUISet, QWidget* parent) | ||||
|     createTunableElementsControl(m_sampleSink->getTunableElements()); | ||||
|     createGlobalGainControl(); | ||||
|     createIndividualGainsControl(m_sampleSink->getIndividualGainsRanges()); | ||||
|     createStreamArgumentsControl(m_sampleSink->getStreamArgInfoList()); | ||||
|     m_sampleSink->initGainSettings(m_settings); | ||||
|     m_sampleSink->initStreamArgSettings(m_settings); | ||||
| 
 | ||||
|     if (m_sampleRateGUI) { | ||||
|         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) | ||||
| { | ||||
|     setObjectName(name); | ||||
| @ -509,6 +593,12 @@ void SoapySDROutputGui::iqCorrectionArgumentChanged(double value) | ||||
|     sendSettings(); | ||||
| } | ||||
| 
 | ||||
| void SoapySDROutputGui::streamArgChanged(QString itemName, QVariant value) | ||||
| { | ||||
|     m_settings.m_streamArgSettings[itemName] = value; | ||||
|     sendSettings(); | ||||
| } | ||||
| 
 | ||||
| void SoapySDROutputGui::on_centerFrequency_changed(quint64 value) | ||||
| { | ||||
|     m_settings.m_centerFrequency = value * 1000; | ||||
| @ -585,6 +675,7 @@ void SoapySDROutputGui::displaySettings() | ||||
|     displayTunableElementsControlSettings(); | ||||
|     displayIndividualGainsControlSettings(); | ||||
|     displayCorrectionsSettings(); | ||||
|     displayStreamArgsSettings(); | ||||
| 
 | ||||
|     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() | ||||
| { | ||||
|     if (!m_updateTimer.isActive()) { | ||||
|  | ||||
| @ -31,6 +31,7 @@ class DeviceUISet; | ||||
| class ItemSettingGUI; | ||||
| class StringRangeGUI; | ||||
| class DynamicItemSettingGUI; | ||||
| class DynamicArgSettingGUI; | ||||
| class IntervalSliderGUI; | ||||
| class QCheckBox; | ||||
| class ComplexFactorGUI; | ||||
| @ -69,6 +70,7 @@ private: | ||||
|     void createGlobalGainControl(); | ||||
|     void createIndividualGainsControl(const std::vector<DeviceSoapySDRParams::GainSetting>& individualGainsList); | ||||
|     void createCorrectionsControl(); | ||||
|     void createStreamArgumentsControl(const SoapySDR::ArgInfoList& argInfoList); | ||||
| 
 | ||||
|     Ui::SoapySDROutputGui* ui; | ||||
| 
 | ||||
| @ -95,12 +97,14 @@ private: | ||||
|     ComplexFactorGUI *m_iqCorrectionGUI; | ||||
|     QCheckBox *m_autoDCCorrection; | ||||
|     QCheckBox *m_autoIQCorrection; | ||||
|     std::vector<DynamicArgSettingGUI*> m_streamArgsGUIs; | ||||
| 
 | ||||
|     void blockApplySettings(bool block) { m_doApplySettings = !block; } | ||||
|     void displaySettings(); | ||||
|     void displayTunableElementsControlSettings(); | ||||
|     void displayIndividualGainsControlSettings(); | ||||
|     void displayCorrectionsSettings(); | ||||
|     void displayStreamArgsSettings(); | ||||
|     void sendSettings(); | ||||
|     void updateSampleRateAndFrequency(); | ||||
|     void updateFrequencyLimits(); | ||||
| @ -122,6 +126,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); | ||||
|  | ||||
| @ -65,6 +65,7 @@ QByteArray SoapySDROutputSettings::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(); | ||||
| } | ||||
| @ -105,6 +106,8 @@ bool SoapySDROutputSettings::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; | ||||
|     } | ||||
| @ -131,3 +134,21 @@ void SoapySDROutputSettings::deserializeNamedElementMap(const QByteArray& data, | ||||
|     (*stream) >> map; | ||||
|     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_ | ||||
| 
 | ||||
| #include <QtGlobal> | ||||
| #include <QVariant> | ||||
| #include <QMap> | ||||
| 
 | ||||
| struct SoapySDROutputSettings { | ||||
| @ -37,6 +38,7 @@ struct SoapySDROutputSettings { | ||||
|     bool m_autoIQCorrection; | ||||
|     std::complex<double> m_dcCorrection; | ||||
|     std::complex<double> m_iqCorrection; | ||||
|     QMap<QString, QVariant> m_streamArgSettings; | ||||
| 
 | ||||
|     SoapySDROutputSettings(); | ||||
|     void resetToDefaults(); | ||||
| @ -46,6 +48,9 @@ struct SoapySDROutputSettings { | ||||
| 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_SAMPLESINK_SOAPYSDROUTPUT_SOAPYSDROUTPUTSETTINGS_H_ */ | ||||
|  | ||||
| @ -156,7 +156,7 @@ QByteArray SoapySDRInputSettings::serializeArgumentMap(const QMap<QString, QVari | ||||
|     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); | ||||
|     (*stream) >> map; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user