1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-07-28 13:04:17 -04:00

SoapySDR support: device arg GUI

This commit is contained in:
f4exb
2018-11-12 01:10:51 +01:00
parent c382913fb4
commit 696e7324a4
15 changed files with 345 additions and 18 deletions
@@ -43,6 +43,7 @@ SoapySDRInput::SoapySDRInput(DeviceSourceAPI *deviceAPI) :
openDevice();
initGainSettings(m_settings);
initStreamArgSettings(m_settings);
initDeviceArgSettings(m_settings);
m_fileSink = new FileRecord(QString("test_%1.sdriq").arg(m_deviceAPI->getDeviceUID()));
m_deviceAPI->addSink(m_fileSink);
@@ -276,6 +277,11 @@ const SoapySDR::ArgInfoList& SoapySDRInput::getStreamArgInfoList()
return channelSettings->m_streamSettingsArgs;
}
const SoapySDR::ArgInfoList& SoapySDRInput::getDeviceArgInfoList()
{
return m_deviceShared.m_deviceParams->getDeviceArgs();
}
void SoapySDRInput::initGainSettings(SoapySDRInputSettings& settings)
{
const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel);
@@ -308,6 +314,24 @@ void SoapySDRInput::initStreamArgSettings(SoapySDRInputSettings& settings)
}
}
void SoapySDRInput::initDeviceArgSettings(SoapySDRInputSettings& settings)
{
settings.m_deviceArgSettings.clear();
for (const auto &it : m_deviceShared.m_deviceParams->getDeviceArgs())
{
if (it.type == SoapySDR::ArgInfo::BOOL) {
settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(it.value == "true");
} else if (it.type == SoapySDR::ArgInfo::INT) {
settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(atoi(it.value.c_str()));
} else if (it.type == SoapySDR::ArgInfo::FLOAT) {
settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(atof(it.value.c_str()));
} else if (it.type == SoapySDR::ArgInfo::STRING) {
settings.m_deviceArgSettings[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);
@@ -777,6 +801,33 @@ bool SoapySDRInput::handleMessage(const Message& message __attribute__((unused))
return true;
}
else if (DeviceSoapySDRShared::MsgReportDeviceArgsChange::match(message))
{
DeviceSoapySDRShared::MsgReportDeviceArgsChange& report = (DeviceSoapySDRShared::MsgReportDeviceArgsChange&) message;
QMap<QString, QVariant> deviceArgSettings = report.getDeviceArgSettings();
for (const auto &oname : m_settings.m_deviceArgSettings.keys())
{
auto nvalue = deviceArgSettings.find(oname);
if (nvalue != deviceArgSettings.end() && (m_settings.m_deviceArgSettings[oname] != *nvalue))
{
m_settings.m_deviceArgSettings[oname] = *nvalue;
qDebug("SoapySDRInput::handleMessage: MsgReportDeviceArgsChange: device argument %s set to %s",
oname.toStdString().c_str(), nvalue->toString().toStdString().c_str());
}
}
// propagate settings to GUI if any
if (getMessageQueueToGUI())
{
DeviceSoapySDRShared::MsgReportDeviceArgsChange *reportToGUI = DeviceSoapySDRShared::MsgReportDeviceArgsChange::create(
m_settings.m_deviceArgSettings);
getMessageQueueToGUI()->push(reportToGUI);
}
return true;
}
else
{
return false;
@@ -789,6 +840,7 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo
bool forwardChangeToBuddies = false;
bool globalGainChanged = false;
bool individualGainsChanged = false;
bool deviceArgsChanged = false;
SoapySDR::Device *dev = m_deviceShared.m_device;
SoapySDRInputThread *inputThread = findThread();
@@ -1060,7 +1112,6 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo
dev->writeSetting(SOAPY_SDR_RX, requestedChannel, oname.toStdString(), nvalue->toString().toStdString());
qDebug("SoapySDRInput::applySettings: stream argument %s set to %s",
oname.toStdString().c_str(), nvalue->toString().toStdString().c_str());
individualGainsChanged = true;
}
catch (const std::exception &ex)
{
@@ -1073,6 +1124,32 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo
}
}
for (const auto &oname : m_settings.m_deviceArgSettings.keys())
{
auto nvalue = settings.m_deviceArgSettings.find(oname);
if (nvalue != settings.m_deviceArgSettings.end() && ((m_settings.m_deviceArgSettings[oname] != *nvalue) || force))
{
if (dev != 0)
{
try
{
dev->writeSetting(oname.toStdString(), nvalue->toString().toStdString());
qDebug("SoapySDRInput::applySettings: device argument %s set to %s",
oname.toStdString().c_str(), nvalue->toString().toStdString().c_str());
}
catch (const std::exception &ex)
{
qCritical("SoapySDRInput::applySettings: cannot set device argument %s to %s: %s",
oname.toStdString().c_str(), nvalue->toString().toStdString().c_str(), ex.what());
}
}
m_settings.m_deviceArgSettings[oname] = *nvalue;
deviceArgsChanged = true;
}
}
if (forwardChangeOwnDSP)
{
int sampleRate = settings.m_devSampleRate/(1<<settings.m_log2Decim);
@@ -1083,7 +1160,7 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo
if (forwardChangeToBuddies)
{
// send to source buddies
// send to buddies
const std::vector<DeviceSourceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
@@ -1110,6 +1187,27 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo
}
}
if (deviceArgsChanged)
{
// send to buddies
const std::vector<DeviceSourceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
for (const auto &itSource : sourceBuddies)
{
DeviceSoapySDRShared::MsgReportDeviceArgsChange *report = DeviceSoapySDRShared::MsgReportDeviceArgsChange::create(
settings.m_deviceArgSettings);
itSource->getSampleSourceInputMessageQueue()->push(report);
}
for (const auto &itSink : sinkBuddies)
{
DeviceSoapySDRShared::MsgReportDeviceArgsChange *report = DeviceSoapySDRShared::MsgReportDeviceArgsChange::create(
settings.m_deviceArgSettings);
itSink->getSampleSinkInputMessageQueue()->push(report);
}
}
m_settings = settings;
if (globalGainChanged || individualGainsChanged)
@@ -156,8 +156,10 @@ public:
const std::vector<DeviceSoapySDRParams::FrequencySetting>& getTunableElements();
const std::vector<DeviceSoapySDRParams::GainSetting>& getIndividualGainsRanges();
const SoapySDR::ArgInfoList& getStreamArgInfoList();
const SoapySDR::ArgInfoList& getDeviceArgInfoList();
void initGainSettings(SoapySDRInputSettings& settings);
void initStreamArgSettings(SoapySDRInputSettings& settings);
void initDeviceArgSettings(SoapySDRInputSettings& settings);
bool hasDCAutoCorrection();
bool hasDCCorrectionValue();
bool hasIQAutoCorrection() { return false; } // not in SoapySDR interface
@@ -70,9 +70,11 @@ SoapySDRInputGui::SoapySDRInputGui(DeviceUISet *deviceUISet, QWidget* parent) :
createTunableElementsControl(m_sampleSource->getTunableElements());
createGlobalGainControl();
createIndividualGainsControl(m_sampleSource->getIndividualGainsRanges());
createStreamArgumentsControl(m_sampleSource->getStreamArgInfoList());
createArgumentsControl(m_sampleSource->getDeviceArgInfoList(), true);
createArgumentsControl(m_sampleSource->getStreamArgInfoList(), false);
m_sampleSource->initGainSettings(m_settings);
m_sampleSource->initStreamArgSettings(m_settings);
m_sampleSource->initDeviceArgSettings(m_settings);
if (m_sampleRateGUI) {
connect(m_sampleRateGUI, SIGNAL(valueChanged(double)), this, SLOT(sampleRateChanged(double)));
@@ -310,7 +312,7 @@ void SoapySDRInputGui::createCorrectionsControl()
}
}
void SoapySDRInputGui::createStreamArgumentsControl(const SoapySDR::ArgInfoList& argInfoList)
void SoapySDRInputGui::createArgumentsControl(const SoapySDR::ArgInfoList& argInfoList, bool deviceArguments)
{
if (argInfoList.size() == 0) { // return early if list is empty
return;
@@ -359,7 +361,10 @@ void SoapySDRInputGui::createStreamArgumentsControl(const SoapySDR::ArgInfoList&
for (int i = 0; optionIt != it->options.end(); ++optionIt, i++)
{
QString name(optionNameIt == it->optionNames.end() ? optionIt->c_str() : optionNameIt->c_str());
++optionNameIt;
if (optionNameIt != it->optionNames.end()) {
++optionNameIt;
}
if (valueType == ArgInfoGUI::ArgInfoValueInt) {
argGUI->addIntValue(name, atoi(optionIt->c_str()));
@@ -385,8 +390,18 @@ void SoapySDRInputGui::createStreamArgumentsControl(const SoapySDR::ArgInfoList&
layout->addWidget(argGUI);
DynamicArgSettingGUI *gui = new DynamicArgSettingGUI(argGUI, QString(it->key.c_str()));
m_streamArgsGUIs.push_back(gui);
connect(gui, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(streamArgChanged(QString, QVariant)));
// This could be made more elegant but let's make it more simple
if (deviceArguments)
{
m_deviceArgsGUIs.push_back(gui);
connect(gui, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(deviceArgChanged(QString, QVariant)));
}
else
{
m_streamArgsGUIs.push_back(gui);
connect(gui, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(streamArgChanged(QString, QVariant)));
}
}
}
@@ -467,6 +482,14 @@ bool SoapySDRInputGui::handleMessage(const Message& message)
return true;
}
else if (DeviceSoapySDRShared::MsgReportDeviceArgsChange::match(message))
{
DeviceSoapySDRShared::MsgReportDeviceArgsChange& notif = (DeviceSoapySDRShared::MsgReportDeviceArgsChange&) message;
m_settings.m_deviceArgSettings = notif.getDeviceArgSettings();
displayDeviceArgsSettings();
return true;
}
else if (SoapySDRInput::MsgStartStop::match(message))
{
SoapySDRInput::MsgStartStop& notif = (SoapySDRInput::MsgStartStop&) message;
@@ -602,6 +625,12 @@ void SoapySDRInputGui::streamArgChanged(QString itemName, QVariant value)
sendSettings();
}
void SoapySDRInputGui::deviceArgChanged(QString itemName, QVariant value)
{
m_settings.m_deviceArgSettings[itemName] = value;
sendSettings();
}
void SoapySDRInputGui::on_centerFrequency_changed(quint64 value)
{
m_settings.m_centerFrequency = value * 1000;
@@ -722,6 +751,7 @@ void SoapySDRInputGui::displaySettings()
displayIndividualGainsControlSettings();
displayCorrectionsSettings();
displayStreamArgsSettings();
displayDeviceArgsSettings();
blockApplySettings(false);
}
@@ -791,6 +821,20 @@ void SoapySDRInputGui::displayStreamArgsSettings()
}
}
void SoapySDRInputGui::displayDeviceArgsSettings()
{
for (const auto &it : m_deviceArgsGUIs)
{
QMap<QString, QVariant>::iterator elIt = m_settings.m_deviceArgSettings.find(it->getName());
if (elIt != m_settings.m_deviceArgSettings.end())
{
it->setValue(*elIt);
*elIt = it->getValue();
}
}
}
void SoapySDRInputGui::sendSettings()
{
if (!m_updateTimer.isActive()) {
@@ -68,7 +68,7 @@ private:
void createGlobalGainControl();
void createIndividualGainsControl(const std::vector<DeviceSoapySDRParams::GainSetting>& individualGainsList);
void createCorrectionsControl();
void createStreamArgumentsControl(const SoapySDR::ArgInfoList& argInfoList);
void createArgumentsControl(const SoapySDR::ArgInfoList& argInfoList, bool deviceArguments);
Ui::SoapySDRInputGui* ui;
@@ -96,12 +96,14 @@ private:
QCheckBox *m_autoDCCorrection;
QCheckBox *m_autoIQCorrection;
std::vector<DynamicArgSettingGUI*> m_streamArgsGUIs;
std::vector<DynamicArgSettingGUI*> m_deviceArgsGUIs;
void displaySettings();
void displayTunableElementsControlSettings();
void displayIndividualGainsControlSettings();
void displayCorrectionsSettings();
void displayStreamArgsSettings();
void displayDeviceArgsSettings();
void sendSettings();
void updateSampleRateAndFrequency();
void updateFrequencyLimits();
@@ -124,6 +126,7 @@ private slots:
void iqCorrectionModuleChanged(double value);
void iqCorrectionArgumentChanged(double value);
void streamArgChanged(QString itemName, QVariant value);
void deviceArgChanged(QString itemName, QVariant value);
void on_centerFrequency_changed(quint64 value);
void on_LOppm_valueChanged(int value);
@@ -72,6 +72,7 @@ QByteArray SoapySDRInputSettings::serialize() const
s.writeDouble(19, m_iqCorrection.real());
s.writeDouble(20, m_iqCorrection.imag());
s.writeBlob(21, serializeArgumentMap(m_streamArgSettings));
s.writeBlob(22, serializeArgumentMap(m_deviceArgSettings));
return s.final();
}
@@ -119,6 +120,8 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data)
m_iqCorrection = std::complex<double>{realval, imagval};
d.readBlob(21, &blob);
deserializeArgumentMap(blob, m_streamArgSettings);
d.readBlob(22, &blob);
deserializeArgumentMap(blob, m_deviceArgSettings);
return true;
}
@@ -50,6 +50,7 @@ struct SoapySDRInputSettings {
std::complex<double> m_dcCorrection;
std::complex<double> m_iqCorrection;
QMap<QString, QVariant> m_streamArgSettings;
QMap<QString, QVariant> m_deviceArgSettings;
SoapySDRInputSettings();
void resetToDefaults();