diff --git a/plugins/channelrx/localsink/localsink.cpp b/plugins/channelrx/localsink/localsink.cpp index b0e7d3684..ef2f54eeb 100644 --- a/plugins/channelrx/localsink/localsink.cpp +++ b/plugins/channelrx/localsink/localsink.cpp @@ -54,6 +54,7 @@ LocalSink::LocalSink(DeviceAPI *deviceAPI) : m_thread(nullptr), m_basebandSink(nullptr), m_running(false), + m_spectrumVis(SDR_RX_SCALEF), m_centerFrequency(0), m_frequencyOffset(0), m_basebandSampleRate(48000) @@ -147,6 +148,7 @@ void LocalSink::startProcessing() qDebug("LocalSink::startProcessing"); m_thread = new QThread(this); m_basebandSink = new LocalSinkBaseband(); + m_basebandSink->setSpectrumSink(&m_spectrumVis); m_basebandSink->moveToThread(m_thread); QObject::connect(m_thread, &QThread::finished, m_basebandSink, &QObject::deleteLater); @@ -163,6 +165,12 @@ void LocalSink::startProcessing() LocalSinkBaseband::MsgConfigureLocalSinkBaseband *msgConfig = LocalSinkBaseband::MsgConfigureLocalSinkBaseband::create(m_settings, true); m_basebandSink->getInputMessageQueue()->push(msgConfig); + LocalSinkBaseband::MsgSetSpectrumSampleRateAndFrequency *msgSpectrum = LocalSinkBaseband::MsgSetSpectrumSampleRateAndFrequency::create( + m_basebandSampleRate / (1 << m_settings.m_log2Decim), + m_centerFrequency + m_frequencyOffset + ); + m_basebandSink->getInputMessageQueue()->push(msgSpectrum); + m_running = true; } @@ -198,6 +206,12 @@ bool LocalSink::handleMessage(const Message& cmd) { DSPSignalNotification *msg = new DSPSignalNotification(notif.getSampleRate(), notif.getCenterFrequency()); m_basebandSink->getInputMessageQueue()->push(msg); + LocalSinkBaseband::MsgSetSpectrumSampleRateAndFrequency *msgSpectrum = + LocalSinkBaseband::MsgSetSpectrumSampleRateAndFrequency::create( + m_basebandSampleRate / (1 << m_settings.m_log2Decim), + m_centerFrequency + m_frequencyOffset + ); + m_basebandSink->getInputMessageQueue()->push(msgSpectrum); } if (getMessageQueueToGUI()) { @@ -336,6 +350,16 @@ void LocalSink::applySettings(const LocalSinkSettings& settings, bool force) { calculateFrequencyOffset(settings.m_log2Decim, settings.m_filterChainHash); propagateSampleRateAndFrequency(m_settings.m_localDeviceIndex, settings.m_log2Decim); + + if (m_running) + { + LocalSinkBaseband::MsgSetSpectrumSampleRateAndFrequency *msgSpectrum = + LocalSinkBaseband::MsgSetSpectrumSampleRateAndFrequency::create( + m_basebandSampleRate / (1 << m_settings.m_log2Decim), + m_centerFrequency + m_frequencyOffset + ); + m_basebandSink->getInputMessageQueue()->push(msgSpectrum); + } } if ((settings.m_play != m_settings.m_play) || force) diff --git a/plugins/channelrx/localsink/localsink.h b/plugins/channelrx/localsink/localsink.h index 75bd5c27a..d59d04e54 100644 --- a/plugins/channelrx/localsink/localsink.h +++ b/plugins/channelrx/localsink/localsink.h @@ -22,6 +22,7 @@ #include #include "dsp/basebandsamplesink.h" +#include "dsp/spectrumvis.h" #include "channel/channelapi.h" #include "util/message.h" @@ -83,6 +84,7 @@ public: virtual void destroy() { delete this; } virtual void setDeviceAPI(DeviceAPI *deviceAPI); virtual DeviceAPI *getDeviceAPI() { return m_deviceAPI; } + SpectrumVis *getSpectrumVis() { return &m_spectrumVis; } using BasebandSampleSink::feed; virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po); @@ -146,6 +148,7 @@ private: bool m_running; LocalSinkSettings m_settings; QList m_localInputDeviceIndexes; + SpectrumVis m_spectrumVis; uint64_t m_centerFrequency; int64_t m_frequencyOffset; diff --git a/plugins/channelrx/localsink/localsinkbaseband.cpp b/plugins/channelrx/localsink/localsinkbaseband.cpp index 10ccc2633..a82d8db7e 100644 --- a/plugins/channelrx/localsink/localsinkbaseband.cpp +++ b/plugins/channelrx/localsink/localsinkbaseband.cpp @@ -20,14 +20,17 @@ #include "dsp/downchannelizer.h" #include "dsp/dspengine.h" #include "dsp/dspcommands.h" +#include "dsp/spectrumvis.h" #include "localsinkbaseband.h" MESSAGE_CLASS_DEFINITION(LocalSinkBaseband::MsgConfigureLocalSinkBaseband, Message) MESSAGE_CLASS_DEFINITION(LocalSinkBaseband::MsgConfigureLocalDeviceSampleSource, Message) +MESSAGE_CLASS_DEFINITION(LocalSinkBaseband::MsgSetSpectrumSampleRateAndFrequency, Message) LocalSinkBaseband::LocalSinkBaseband() : - m_localSampleSource(nullptr) + m_localSampleSource(nullptr), + m_spectrumVis(nullptr) { m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000)); m_channelizer = new DownChannelizer(&m_sink); @@ -137,6 +140,18 @@ bool LocalSinkBaseband::handleMessage(const Message& cmd) return true; } + else if (MsgSetSpectrumSampleRateAndFrequency::match(cmd)) + { + MsgSetSpectrumSampleRateAndFrequency& notif = (MsgSetSpectrumSampleRateAndFrequency&) cmd; + + if (m_spectrumVis) + { + DSPSignalNotification *msg = new DSPSignalNotification(notif.getSampleRate(), notif.getCenterFrequency()); + m_spectrumVis->getInputMessageQueue()->push(msg); + } + + return true; + } else { return false; diff --git a/plugins/channelrx/localsink/localsinkbaseband.h b/plugins/channelrx/localsink/localsinkbaseband.h index 5a520ef81..95b5908d2 100644 --- a/plugins/channelrx/localsink/localsinkbaseband.h +++ b/plugins/channelrx/localsink/localsinkbaseband.h @@ -77,6 +77,28 @@ public: DeviceSampleSource *m_deviceSampleSource; }; + class MsgSetSpectrumSampleRateAndFrequency : public Message { + MESSAGE_CLASS_DECLARATION + + public: + static MsgSetSpectrumSampleRateAndFrequency* create(int sampleRate, qint64 centerFrequency) { + return new MsgSetSpectrumSampleRateAndFrequency(sampleRate, centerFrequency); + } + + int getSampleRate() const { return m_sampleRate; } + qint64 getCenterFrequency() const { return m_centerFrequency; } + + private: + MsgSetSpectrumSampleRateAndFrequency(int sampleRate, qint64 centerFrequency) : + Message(), + m_sampleRate(sampleRate), + m_centerFrequency(centerFrequency) + { } + + int m_sampleRate; + qint64 m_centerFrequency; + }; + LocalSinkBaseband(); ~LocalSinkBaseband(); void reset(); @@ -86,6 +108,7 @@ public: void startSource() { m_sink.start(m_localSampleSource); } void stopSource() { m_sink.stop(); } void setFifoLabel(const QString& label) { m_sampleFifo.setLabel(label); } + void setSpectrumSink(SpectrumVis* spectrumSink) { m_spectrumVis = spectrumSink; m_sink.setSpectrumSink(spectrumSink); } private: SampleSinkFifo m_sampleFifo; @@ -94,6 +117,7 @@ private: MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication LocalSinkSettings m_settings; DeviceSampleSource *m_localSampleSource; + SpectrumVis *m_spectrumVis; QRecursiveMutex m_mutex; bool handleMessage(const Message& cmd); diff --git a/plugins/channelrx/localsink/localsinkgui.cpp b/plugins/channelrx/localsink/localsinkgui.cpp index 162c49220..38369f1fc 100644 --- a/plugins/channelrx/localsink/localsinkgui.cpp +++ b/plugins/channelrx/localsink/localsinkgui.cpp @@ -83,6 +83,7 @@ bool LocalSinkGUI::handleMessage(const Message& message) const LocalSink::MsgConfigureLocalSink& cfg = (LocalSink::MsgConfigureLocalSink&) message; m_settings = cfg.getSettings(); blockApplySettings(true); + ui->spectrumGUI->updateSettings(); m_channelMarker.updateSettings(static_cast(m_settings.m_channelMarker)); displaySettings(); blockApplySettings(false); @@ -119,8 +120,13 @@ LocalSinkGUI::LocalSinkGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseb connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &))); m_localSink = (LocalSink*) channelrx; + m_spectrumVis = m_localSink->getSpectrumVis(); + m_spectrumVis->setGLSpectrum(ui->glSpectrum); m_localSink->setMessageQueueToGUI(getInputMessageQueue()); + ui->glSpectrum->setCenterFrequency(m_deviceCenterFrequency); + ui->glSpectrum->setSampleRate(m_basebandSampleRate); + m_channelMarker.blockSignals(true); m_channelMarker.setColor(m_settings.m_rgbColor); m_channelMarker.setCenterFrequency(0); @@ -129,11 +135,13 @@ LocalSinkGUI::LocalSinkGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseb m_channelMarker.setVisible(true); // activate signal on the last setting only m_settings.setChannelMarker(&m_channelMarker); + m_settings.setSpectrumGUI(ui->spectrumGUI); m_settings.setRollupState(&m_rollupState); m_deviceUISet->addChannelMarker(&m_channelMarker); connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages())); + ui->spectrumGUI->setBuddies(m_spectrumVis, ui->glSpectrum); updateDeviceSetList(m_localSink->getDeviceSetList()); displaySettings(); @@ -199,6 +207,8 @@ void LocalSinkGUI::displayRateAndShift() QLocale loc; ui->offsetFrequencyText->setText(tr("%1 Hz").arg(loc.toString(shift))); ui->channelRateText->setText(tr("%1k").arg(QString::number(channelSampleRate / 1000.0, 'g', 5))); + ui->glSpectrum->setSampleRate(channelSampleRate); + ui->glSpectrum->setCenterFrequency(m_deviceCenterFrequency + shift); m_channelMarker.setCenterFrequency(shift); m_channelMarker.setBandwidth(channelSampleRate); } diff --git a/plugins/channelrx/localsink/localsinkgui.h b/plugins/channelrx/localsink/localsinkgui.h index a5947d416..32df9a8d6 100644 --- a/plugins/channelrx/localsink/localsinkgui.h +++ b/plugins/channelrx/localsink/localsinkgui.h @@ -33,6 +33,7 @@ class PluginAPI; class DeviceUISet; class LocalSink; class BasebandSampleSink; +class SpectrumVis; namespace Ui { class LocalSinkGUI; @@ -73,6 +74,7 @@ private: bool m_doApplySettings; LocalSink* m_localSink; + SpectrumVis* m_spectrumVis; MessageQueue m_inputMessageQueue; uint32_t m_tickCount; diff --git a/plugins/channelrx/localsink/localsinkgui.ui b/plugins/channelrx/localsink/localsinkgui.ui index a1ef5e211..64e3e118c 100644 --- a/plugins/channelrx/localsink/localsinkgui.ui +++ b/plugins/channelrx/localsink/localsinkgui.ui @@ -6,26 +6,20 @@ 0 0 - 320 - 110 + 414 + 406 - + 0 0 - 320 - 100 - - - - - 560 - 16777215 + 414 + 0 @@ -42,7 +36,7 @@ 10 10 - 302 + 401 91 @@ -313,6 +307,80 @@ + + + + 10 + 110 + 218 + 284 + + + + + 0 + 0 + + + + Channel Spectrum + + + + 2 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + 0 + 0 + + + + + 200 + 250 + + + + + Liberation Mono + 8 + + + + + + + + + 0 + 0 + + + + + 0 + 30 + + + + + + @@ -326,6 +394,18 @@
gui/rollupcontents.h
1
+ + GLSpectrum + QWidget +
gui/glspectrum.h
+ 1 +
+ + GLSpectrumGUI + QWidget +
gui/glspectrumgui.h
+ 1 +
diff --git a/plugins/channelrx/localsink/localsinksettings.h b/plugins/channelrx/localsink/localsinksettings.h index 93cd41785..f5290ddf6 100644 --- a/plugins/channelrx/localsink/localsinksettings.h +++ b/plugins/channelrx/localsink/localsinksettings.h @@ -41,11 +41,13 @@ struct LocalSinkSettings QByteArray m_geometryBytes; bool m_hidden; + Serializable *m_spectrumGUI; Serializable *m_channelMarker; Serializable *m_rollupState; LocalSinkSettings(); void resetToDefaults(); + void setSpectrumGUI(Serializable *spectrumGUI) { m_spectrumGUI = spectrumGUI; } void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; } void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; } QByteArray serialize() const; diff --git a/plugins/channelrx/localsink/localsinksink.cpp b/plugins/channelrx/localsink/localsinksink.cpp index 777d25ae1..77d871806 100644 --- a/plugins/channelrx/localsink/localsinksink.cpp +++ b/plugins/channelrx/localsink/localsinksink.cpp @@ -21,6 +21,7 @@ #include #include "dsp/devicesamplesource.h" #include "dsp/hbfilterchainconverter.h" +#include "dsp/spectrumvis.h" #include "localsinkworker.h" #include "localsinksink.h" @@ -28,6 +29,7 @@ LocalSinkSink::LocalSinkSink() : m_deviceSource(nullptr), m_sinkWorker(nullptr), + m_spectrumSink(nullptr), m_running(false), m_centerFrequency(0), m_frequencyOffset(0), @@ -47,6 +49,10 @@ void LocalSinkSink::feed(const SampleVector::const_iterator& begin, const Sample if (m_running && m_deviceSource) { m_deviceSource->getSampleFifo()->write(begin, end); } + + if (m_spectrumSink) { + m_spectrumSink->feed(begin, end, false); + } // m_sampleFifo.write(begin, end); } diff --git a/plugins/channelrx/localsink/localsinksink.h b/plugins/channelrx/localsink/localsinksink.h index 2552f4dca..480a227f2 100644 --- a/plugins/channelrx/localsink/localsinksink.h +++ b/plugins/channelrx/localsink/localsinksink.h @@ -27,6 +27,7 @@ class DeviceSampleSource; class LocalSinkWorker; +class SpectrumVis; class LocalSinkSink : public QObject, public ChannelSampleSink { Q_OBJECT @@ -36,6 +37,7 @@ public: virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end); + void setSpectrumSink(SpectrumVis* spectrumSink) { m_spectrumSink = spectrumSink; } void applySettings(const LocalSinkSettings& settings, bool force = false); void start(DeviceSampleSource *deviceSource); void stop(); @@ -48,6 +50,8 @@ private: LocalSinkSettings m_settings; LocalSinkWorker *m_sinkWorker; QThread m_sinkWorkerThread; + SpectrumVis* m_spectrumSink; + SampleVector m_spectrumBuffer; bool m_running; uint64_t m_centerFrequency;