1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-09-27 15:26:33 -04:00

Local Sink: added spectrum monitor

This commit is contained in:
f4exb 2022-12-04 02:52:02 +01:00
parent 551f7cbcd3
commit 2754e3ea5e
10 changed files with 183 additions and 13 deletions

View File

@ -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)

View File

@ -22,6 +22,7 @@
#include <QNetworkRequest>
#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<int> m_localInputDeviceIndexes;
SpectrumVis m_spectrumVis;
uint64_t m_centerFrequency;
int64_t m_frequencyOffset;

View File

@ -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;

View File

@ -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);

View File

@ -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<const ChannelMarker*>(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);
}

View File

@ -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;

View File

@ -6,26 +6,20 @@
<rect>
<x>0</x>
<y>0</y>
<width>320</width>
<height>110</height>
<width>414</width>
<height>406</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>320</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>560</width>
<height>16777215</height>
<width>414</width>
<height>0</height>
</size>
</property>
<property name="font">
@ -42,7 +36,7 @@
<rect>
<x>10</x>
<y>10</y>
<width>302</width>
<width>401</width>
<height>91</height>
</rect>
</property>
@ -313,6 +307,80 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="spectrumContainer" native="true">
<property name="geometry">
<rect>
<x>10</x>
<y>110</y>
<width>218</width>
<height>284</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Channel Spectrum</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="GLSpectrum" name="glSpectrum" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>250</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Mono</family>
<pointsize>8</pointsize>
</font>
</property>
</widget>
</item>
<item>
<widget class="GLSpectrumGUI" name="spectrumGUI" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
@ -326,6 +394,18 @@
<header>gui/rollupcontents.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GLSpectrum</class>
<extends>QWidget</extends>
<header>gui/glspectrum.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GLSpectrumGUI</class>
<extends>QWidget</extends>
<header>gui/glspectrumgui.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../../sdrgui/resources/res.qrc"/>

View File

@ -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;

View File

@ -21,6 +21,7 @@
#include <boost/cstdint.hpp>
#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);
}

View File

@ -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;