From c1b03bfc429b554c26ddec3e92307590bd4daafd Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 2 Sep 2019 18:37:36 +0200 Subject: [PATCH] Interferometer (3): plugin --- .../channelmimo/interferometer/CMakeLists.txt | 2 + .../interferometer/interferometer.cpp | 60 ++++++++++++- .../interferometer/interferometer.h | 23 ++++- .../interferometer/interferometerplugin.cpp | 85 +++++++++++++++++++ .../interferometer/interferometerplugin.h | 50 +++++++++++ 5 files changed, 218 insertions(+), 2 deletions(-) create mode 100644 plugins/channelmimo/interferometer/interferometerplugin.cpp create mode 100644 plugins/channelmimo/interferometer/interferometerplugin.h diff --git a/plugins/channelmimo/interferometer/CMakeLists.txt b/plugins/channelmimo/interferometer/CMakeLists.txt index b6aa9bf80..65176dd8c 100644 --- a/plugins/channelmimo/interferometer/CMakeLists.txt +++ b/plugins/channelmimo/interferometer/CMakeLists.txt @@ -1,6 +1,7 @@ project(interferometer) set(interferometer_SOURCES + interferometerplugin.cpp interferometer.cpp interferometercorr.cpp interferometersettings.cpp @@ -10,6 +11,7 @@ set(interferometer_SOURCES ) set(interferometer_HEADERS + interferometerplugin.h interferometer.h interferometercorr.h interferometersettings.h diff --git a/plugins/channelmimo/interferometer/interferometer.cpp b/plugins/channelmimo/interferometer/interferometer.cpp index 834cce90d..7e0bcab75 100644 --- a/plugins/channelmimo/interferometer/interferometer.cpp +++ b/plugins/channelmimo/interferometer/interferometer.cpp @@ -24,6 +24,8 @@ #include "device/deviceapi.h" #include "dsp/downchannelizer.h" #include "dsp/threadedbasebandsamplesink.h" +#include "dsp/hbfilterchainconverter.h" +#include "dsp/dspcommands.h" #include "SWGChannelSettings.h" @@ -41,7 +43,9 @@ Interferometer::Interferometer(DeviceAPI *deviceAPI) : ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), m_deviceAPI(deviceAPI), m_spectrumSink(nullptr), - m_scopeSink(nullptr) + m_scopeSink(nullptr), + m_frequencyOffset(0), + m_deviceSampleRate(48000) { m_deviceAPI->addChannelSinkAPI(this); m_thread = new QThread(this); @@ -110,12 +114,60 @@ bool Interferometer::handleMessage(const Message& cmd) applySettings(cfg.getSettings(), cfg.getForce()); return true; } + else if (DSPSignalNotification::match(cmd)) + { + DSPSignalNotification& notif = (DSPSignalNotification&) cmd; + + qDebug() << "Interferometer::handleMessage: DSPSignalNotification:" + << " inputSampleRate: " << notif.getSampleRate() + << " centerFrequency: " << notif.getCenterFrequency(); + + m_deviceSampleRate = notif.getSampleRate(); + calculateFrequencyOffset(); // This is when device sample rate changes + + // Redo the channelizer stuff with the new sample rate to re-synchronize everything + InterferometerSink::MsgConfigureChannelizer *msg = InterferometerSink::MsgConfigureChannelizer::create( + m_settings.m_log2Decim, + m_settings.m_filterChainHash); + m_sink->getInputMessageQueue()->push(msg); + + if (m_guiMessageQueue) + { + MsgSampleRateNotification *msg = MsgSampleRateNotification::create(notif.getSampleRate()); + m_guiMessageQueue->push(msg); + } + + return true; + } else { return false; } } +QByteArray Interferometer::serialize() const +{ + return m_settings.serialize(); +} + +bool Interferometer::deserialize(const QByteArray& data) +{ + (void) data; + if (m_settings.deserialize(data)) + { + MsgConfigureInterferometer *msg = MsgConfigureInterferometer::create(m_settings, true); + m_inputMessageQueue.push(msg); + return true; + } + else + { + m_settings.resetToDefaults(); + MsgConfigureInterferometer *msg = MsgConfigureInterferometer::create(m_settings, true); + m_inputMessageQueue.push(msg); + return false; + } +} + void Interferometer::validateFilterChainHash(InterferometerSettings& settings) { unsigned int s = 1; @@ -127,6 +179,12 @@ void Interferometer::validateFilterChainHash(InterferometerSettings& settings) settings.m_filterChainHash = settings.m_filterChainHash >= s ? s-1 : settings.m_filterChainHash; } +void Interferometer::calculateFrequencyOffset() +{ + double shiftFactor = HBFilterChainConverter::getShiftFactor(m_settings.m_log2Decim, m_settings.m_filterChainHash); + m_frequencyOffset = m_deviceSampleRate * shiftFactor; +} + int Interferometer::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) diff --git a/plugins/channelmimo/interferometer/interferometer.h b/plugins/channelmimo/interferometer/interferometer.h index 28c4fc8d5..4998fbfd0 100644 --- a/plugins/channelmimo/interferometer/interferometer.h +++ b/plugins/channelmimo/interferometer/interferometer.h @@ -35,7 +35,7 @@ class QNetworkReply; class QNetworkAccessManager; class BasebandSampleSink; -class Interferometer: public MIMOSampleSink, ChannelAPI +class Interferometer: public MIMOSampleSink, public ChannelAPI { Q_OBJECT public: @@ -113,6 +113,23 @@ public: virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, unsigned int sinkIndex); virtual bool handleMessage(const Message& cmd); //!< Processing of a message. Returns true if message has actually been processed + virtual void getIdentifier(QString& id) { id = objectName(); } + virtual void getTitle(QString& title) { title = "Interferometer"; } + virtual qint64 getCenterFrequency() const { return m_frequencyOffset; } + + virtual QByteArray serialize() const; + virtual bool deserialize(const QByteArray& data); + + virtual int getNbSinkStreams() const { return 2; } + virtual int getNbSourceStreams() const { return 0; } + + virtual qint64 getStreamCenterFrequency(int streamIndex, bool sinkElseSource) const + { + (void) streamIndex; + (void) sinkElseSource; + return m_frequencyOffset; + } + MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; } MessageQueue *getMessageQueueToGUI() { return m_guiMessageQueue; } @@ -155,8 +172,12 @@ private: QNetworkAccessManager *m_networkManager; QNetworkRequest m_networkRequest; + int64_t m_frequencyOffset; + uint32_t m_deviceSampleRate; + void applySettings(const InterferometerSettings& settings, bool force = false); static void validateFilterChainHash(InterferometerSettings& settings); + void calculateFrequencyOffset(); void webapiReverseSendSettings(QList& channelSettingsKeys, const InterferometerSettings& settings, bool force); private slots: diff --git a/plugins/channelmimo/interferometer/interferometerplugin.cpp b/plugins/channelmimo/interferometer/interferometerplugin.cpp new file mode 100644 index 000000000..9ee31d514 --- /dev/null +++ b/plugins/channelmimo/interferometer/interferometerplugin.cpp @@ -0,0 +1,85 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2019 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "interferometerplugin.h" + +#include +#include "plugin/pluginapi.h" + +#ifndef SERVER_MODE +#include "interferometergui.h" +#endif +#include "interferometer.h" +#include "interferometerwebapiadapter.h" +#include "interferometerplugin.h" + +const PluginDescriptor InterferometerPlugin::m_pluginDescriptor = { + QString("Interferometer"), + QString("4.12.0"), + QString("(c) Edouard Griffiths, F4EXB"), + QString("https://github.com/f4exb/sdrangel"), + true, + QString("https://github.com/f4exb/sdrangel") +}; + +InterferometerPlugin::InterferometerPlugin(QObject* parent) : + QObject(parent), + m_pluginAPI(0) +{ +} + +const PluginDescriptor& InterferometerPlugin::getPluginDescriptor() const +{ + return m_pluginDescriptor; +} + +void InterferometerPlugin::initPlugin(PluginAPI* pluginAPI) +{ + m_pluginAPI = pluginAPI; + + // register channel MIMO + m_pluginAPI->registerMIMOChannel(Interferometer::m_channelIdURI, Interferometer::m_channelId, this); +} + +#ifdef SERVER_MODE +PluginInstanceGUI* InterferometerPlugin::createRxChannelGUI( + DeviceUISet *deviceUISet, + MIMOSampleSink *mimoChannel) const +{ + return 0; +} +#else +PluginInstanceGUI* InterferometerPlugin::createMIMOChannelGUI(DeviceUISet *deviceUISet, MIMOSampleSink *mimoChannel) const +{ + return InterferometerGUI::create(m_pluginAPI, deviceUISet, mimoChannel); +} +#endif + +MIMOSampleSink* InterferometerPlugin::createMIMOChannelBS(DeviceAPI *deviceAPI) const +{ + return new Interferometer(deviceAPI); +} + +ChannelAPI* InterferometerPlugin::createMIMOChannelCS(DeviceAPI *deviceAPI) const +{ + return new Interferometer(deviceAPI); +} + +ChannelWebAPIAdapter* InterferometerPlugin::createChannelWebAPIAdapter() const +{ + return new InterferometerWebAPIAdapter(); +} diff --git a/plugins/channelmimo/interferometer/interferometerplugin.h b/plugins/channelmimo/interferometer/interferometerplugin.h new file mode 100644 index 000000000..0a39fceca --- /dev/null +++ b/plugins/channelmimo/interferometer/interferometerplugin.h @@ -0,0 +1,50 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2019 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef PLUGINS_CHANNELMIMO_INTERFEROMETER_INTERFEROMETERPLUGIN_H_ +#define PLUGINS_CHANNELMIMO_INTERFEROMETER_INTERFEROMETERPLUGIN_H_ + + +#include +#include "plugin/plugininterface.h" + +class DeviceUISet; +class MIMOSampleSink; + +class InterferometerPlugin : public QObject, PluginInterface { + Q_OBJECT + Q_INTERFACES(PluginInterface) + Q_PLUGIN_METADATA(IID "sdrangel.channelmimo.interferometer") + +public: + explicit InterferometerPlugin(QObject* parent = nullptr); + + const PluginDescriptor& getPluginDescriptor() const; + void initPlugin(PluginAPI* pluginAPI); + + virtual PluginInstanceGUI* createMIMOChannelGUI(DeviceUISet *deviceUISet, MIMOSampleSink *mimoChannel) const; + virtual MIMOSampleSink* createMIMOChannelBS(DeviceAPI *deviceAPI) const; + virtual ChannelAPI* createMIMOChannelCS(DeviceAPI *deviceAPI) const; + virtual ChannelWebAPIAdapter* createChannelWebAPIAdapter() const; + +private: + static const PluginDescriptor m_pluginDescriptor; + + PluginAPI* m_pluginAPI; +}; + +#endif /* PLUGINS_CHANNELMIMO_INTERFEROMETER_INTERFEROMETERPLUGIN_H_ */