From 59c8ecd2d0d1cfc104612eacc478f22d51f99926 Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 7 Nov 2018 23:54:32 +0100 Subject: [PATCH] SoapySDR support: output: manage global and individual gains coupling --- .../soapysdroutput/soapysdroutput.cpp | 47 ++++++++++++++++++- .../soapysdroutput/soapysdroutput.h | 28 +++++++++++ .../soapysdroutput/soapysdroutputgui.cpp | 19 ++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/plugins/samplesink/soapysdroutput/soapysdroutput.cpp b/plugins/samplesink/soapysdroutput/soapysdroutput.cpp index 9050ef98b..a54e3dc9a 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutput.cpp +++ b/plugins/samplesink/soapysdroutput/soapysdroutput.cpp @@ -28,6 +28,7 @@ MESSAGE_CLASS_DEFINITION(SoapySDROutput::MsgConfigureSoapySDROutput, Message) MESSAGE_CLASS_DEFINITION(SoapySDROutput::MsgStartStop, Message) +MESSAGE_CLASS_DEFINITION(SoapySDROutput::MsgReportGainChange, Message) SoapySDROutput::SoapySDROutput(DeviceSinkAPI *deviceAPI) : m_deviceAPI(deviceAPI), @@ -36,6 +37,7 @@ SoapySDROutput::SoapySDROutput(DeviceSinkAPI *deviceAPI) : m_thread(0) { openDevice(); + initGainSettings(m_settings); } SoapySDROutput::~SoapySDROutput() @@ -230,6 +232,19 @@ const std::vector& SoapySDROutput::getIndivid return channelSettings->m_gainSettings; } +void SoapySDROutput::initGainSettings(SoapySDROutputSettings& settings) +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel); + settings.m_individualGains.clear(); + settings.m_globalGain = 0; + + for (const auto &it : channelSettings->m_gainSettings) { + settings.m_individualGains[QString(it.m_name.c_str())] = 0.0; + } + + updateGains(m_deviceShared.m_device, m_deviceShared.m_channel, settings); +} + void SoapySDROutput::init() { applySettings(m_settings, true); @@ -585,6 +600,19 @@ bool SoapySDROutput::setDeviceCenterFrequency(SoapySDR::Device *dev, int request } } +void SoapySDROutput::updateGains(SoapySDR::Device *dev, int requestedChannel, SoapySDROutputSettings& settings) +{ + if (dev == 0) { + return; + } + + settings.m_globalGain = round(dev->getGain(SOAPY_SDR_TX, requestedChannel)); + + for (const auto &name : settings.m_individualGains.keys()) { + settings.m_individualGains[name] = dev->getGain(SOAPY_SDR_TX, requestedChannel, name.toStdString()); + } +} + bool SoapySDROutput::handleMessage(const Message& message) { if (MsgConfigureSoapySDROutput::match(message)) @@ -656,6 +684,8 @@ bool SoapySDROutput::applySettings(const SoapySDROutputSettings& settings, bool { bool forwardChangeOwnDSP = false; bool forwardChangeToBuddies = false; + bool globalGainChanged = false; + bool individualGainsChanged = false; SoapySDR::Device *dev = m_deviceShared.m_device; SoapySDROutputThread *outputThread = findThread(); @@ -822,6 +852,7 @@ bool SoapySDROutput::applySettings(const SoapySDROutputSettings& settings, bool { dev->setGain(SOAPY_SDR_TX, requestedChannel, settings.m_globalGain); qDebug("SoapySDROutput::applySettings: set global gain to %d", settings.m_globalGain); + globalGainChanged = true; } catch (const std::exception &ex) { @@ -835,7 +866,7 @@ bool SoapySDROutput::applySettings(const SoapySDROutputSettings& settings, bool { auto nvalue = settings.m_individualGains.find(oname); - if (nvalue != settings.m_individualGains.end() && (m_settings.m_individualGains[oname] != *nvalue)) + if (nvalue != settings.m_individualGains.end() && ((m_settings.m_individualGains[oname] != *nvalue) || force)) { if (dev != 0) { @@ -844,6 +875,7 @@ bool SoapySDROutput::applySettings(const SoapySDROutputSettings& settings, bool dev->setGain(SOAPY_SDR_TX, requestedChannel, oname.toStdString(), *nvalue); qDebug("SoapySDROutput::applySettings: individual gain %s set to %lf", oname.toStdString().c_str(), *nvalue); + individualGainsChanged = true; } catch (const std::exception &ex) { @@ -894,6 +926,19 @@ bool SoapySDROutput::applySettings(const SoapySDROutputSettings& settings, bool m_settings = settings; + if (globalGainChanged || individualGainsChanged) + { + if (dev) { + updateGains(dev, requestedChannel, m_settings); + } + + if (getMessageQueueToGUI()) + { + MsgReportGainChange *report = MsgReportGainChange::create(m_settings, individualGainsChanged, globalGainChanged); + getMessageQueueToGUI()->push(report); + } + } + qDebug() << "SoapySDROutput::applySettings: " << " m_transverterMode: " << m_settings.m_transverterMode << " m_transverterDeltaFrequency: " << m_settings.m_transverterDeltaFrequency diff --git a/plugins/samplesink/soapysdroutput/soapysdroutput.h b/plugins/samplesink/soapysdroutput/soapysdroutput.h index 4089fcd9c..12ee21b57 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutput.h +++ b/plugins/samplesink/soapysdroutput/soapysdroutput.h @@ -59,6 +59,32 @@ public: { } }; + class MsgReportGainChange : public Message { + MESSAGE_CLASS_DECLARATION + + public: + const SoapySDROutputSettings& getSettings() const { return m_settings; } + bool getGlobalGain() const { return m_globalGain; } + bool getIndividualGains() const { return m_individualGains; } + + static MsgReportGainChange* create(const SoapySDROutputSettings& settings, bool globalGain, bool individualGains) + { + return new MsgReportGainChange(settings, globalGain, individualGains); + } + + private: + SoapySDROutputSettings m_settings; + bool m_globalGain; + bool m_individualGains; + + MsgReportGainChange(const SoapySDROutputSettings& settings, bool globalGain, bool individualGains) : + Message(), + m_settings(settings), + m_globalGain(globalGain), + m_individualGains(individualGains) + { } + }; + class MsgStartStop : public Message { MESSAGE_CLASS_DECLARATION @@ -106,6 +132,7 @@ public: const SoapySDR::RangeList& getBandwidthRanges(); const std::vector& getTunableElements(); const std::vector& getIndividualGainsRanges(); + void initGainSettings(SoapySDROutputSettings& settings); private: DeviceSinkAPI *m_deviceAPI; @@ -122,6 +149,7 @@ private: void moveThreadToBuddy(); bool applySettings(const SoapySDROutputSettings& settings, bool force = false); bool setDeviceCenterFrequency(SoapySDR::Device *dev, int requestedChannel, quint64 freq_hz, int loPpmTenths); + void updateGains(SoapySDR::Device *dev, int requestedChannel, SoapySDROutputSettings& settings); }; diff --git a/plugins/samplesink/soapysdroutput/soapysdroutputgui.cpp b/plugins/samplesink/soapysdroutput/soapysdroutputgui.cpp index 75f9ae9fd..1b9fc81d6 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutputgui.cpp +++ b/plugins/samplesink/soapysdroutput/soapysdroutputgui.cpp @@ -59,6 +59,7 @@ SoapySDROutputGui::SoapySDROutputGui(DeviceUISet *deviceUISet, QWidget* parent) createTunableElementsControl(m_sampleSink->getTunableElements()); createGlobalGainControl(); createIndividualGainsControl(m_sampleSink->getIndividualGainsRanges()); + m_sampleSink->initGainSettings(m_settings); if (m_sampleRateGUI) { connect(m_sampleRateGUI, SIGNAL(valueChanged(double)), this, SLOT(sampleRateChanged(double))); @@ -282,6 +283,24 @@ bool SoapySDROutputGui::handleMessage(const Message& message) return true; } + else if (SoapySDROutput::MsgReportGainChange::match(message)) + { + const SoapySDROutput::MsgReportGainChange& report = (SoapySDROutput::MsgReportGainChange&) message; + const SoapySDROutputSettings& gainSettings = report.getSettings(); + + if (report.getGlobalGain()) { + m_settings.m_globalGain = gainSettings.m_globalGain; + } + if (report.getIndividualGains()) { + m_settings.m_individualGains = gainSettings.m_individualGains; + } + + blockApplySettings(true); + displaySettings(); + blockApplySettings(false); + + return true; + } else if (SoapySDROutput::MsgStartStop::match(message)) { SoapySDROutput::MsgStartStop& notif = (SoapySDROutput::MsgStartStop&) message;