TestSink spectrum display

This commit is contained in:
f4exb 2019-10-28 01:26:33 +01:00
parent 077a083336
commit dce1951e94
9 changed files with 132 additions and 13 deletions

View File

@ -25,6 +25,7 @@
#include "plugin/pluginapi.h"
#include "gui/colormapper.h"
#include "gui/glspectrum.h"
#include "dsp/spectrumvis.h"
#include "dsp/dspengine.h"
#include "dsp/dspcommands.h"
@ -41,7 +42,6 @@ TestSinkGui::TestSinkGui(DeviceUISet *deviceUISet, QWidget* parent) :
m_doApplySettings(true),
m_forceSettings(true),
m_settings(),
m_deviceSampleSink(0),
m_sampleRate(0),
m_generation(false),
m_samplesCount(0),
@ -49,6 +49,7 @@ TestSinkGui::TestSinkGui(DeviceUISet *deviceUISet, QWidget* parent) :
m_lastEngineState(DeviceAPI::StNotStarted)
{
ui->setupUi(this);
m_sampleSink = (TestSinkOutput*) m_deviceUISet->m_deviceAPI->getSampleSink();
ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->centerFrequency->setValueRange(7, 0, pow(10,7));
@ -56,6 +57,13 @@ TestSinkGui::TestSinkGui(DeviceUISet *deviceUISet, QWidget* parent) :
ui->sampleRate->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
ui->sampleRate->setValueRange(7, 32000U, 9000000U);
m_spectrumVis = new SpectrumVis(SDR_TX_SCALEF, ui->glSpectrum);
m_sampleSink->setSpectrumSink(m_spectrumVis);
ui->glSpectrum->setCenterFrequency(m_settings.m_centerFrequency);
ui->glSpectrum->setSampleRate(m_settings.m_sampleRate*(1<<m_settings.m_log2Interp));
ui->glSpectrum->connectTimer(MainWindow::getInstance()->getMasterTimer());
ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum);
connect(&(m_deviceUISet->m_deviceAPI->getMasterTimer()), SIGNAL(timeout()), this, SLOT(tick()));
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
@ -63,12 +71,12 @@ TestSinkGui::TestSinkGui(DeviceUISet *deviceUISet, QWidget* parent) :
displaySettings();
m_deviceSampleSink = (TestSinkOutput*) m_deviceUISet->m_deviceAPI->getSampleSink();
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
}
TestSinkGui::~TestSinkGui()
{
delete m_spectrumVis;
delete ui;
}
@ -202,7 +210,7 @@ void TestSinkGui::updateHardware()
{
qDebug() << "TestSinkGui::updateHardware";
TestSinkOutput::MsgConfigureTestSink* message = TestSinkOutput::MsgConfigureTestSink::create(m_settings, m_forceSettings);
m_deviceSampleSink->getInputMessageQueue()->push(message);
m_sampleSink->getInputMessageQueue()->push(message);
m_forceSettings = false;
m_updateTimer.stop();
}
@ -239,12 +247,14 @@ void TestSinkGui::updateStatus()
void TestSinkGui::on_centerFrequency_changed(quint64 value)
{
m_settings.m_centerFrequency = value * 1000;
ui->glSpectrum->setCenterFrequency(m_settings.m_centerFrequency);
sendSettings();
}
void TestSinkGui::on_sampleRate_changed(quint64 value)
{
m_settings.m_sampleRate = value;
ui->glSpectrum->setSampleRate(m_settings.m_sampleRate*(1<<m_settings.m_log2Interp));
sendSettings();
}
@ -255,6 +265,7 @@ void TestSinkGui::on_interp_currentIndexChanged(int index)
}
m_settings.m_log2Interp = index;
ui->glSpectrum->setSampleRate(m_settings.m_sampleRate*(1<<m_settings.m_log2Interp));
updateSampleRateAndFrequency();
sendSettings();
}
@ -264,7 +275,7 @@ void TestSinkGui::on_startStop_toggled(bool checked)
if (m_doApplySettings)
{
TestSinkOutput::MsgStartStop *message = TestSinkOutput::MsgStartStop::create(checked);
m_deviceSampleSink->getInputMessageQueue()->push(message);
m_sampleSink->getInputMessageQueue()->push(message);
}
}

View File

@ -28,8 +28,9 @@
#include "testsinksettings.h"
class DeviceSampleSink;
class TestSinkOutput;
class DeviceUISet;
class SpectrumVis;
namespace Ui {
class TestSinkGui;
@ -63,7 +64,7 @@ private:
TestSinkSettings m_settings;
QTimer m_updateTimer;
QTimer m_statusTimer;
DeviceSampleSink* m_deviceSampleSink;
TestSinkOutput* m_sampleSink;
int m_sampleRate;
quint64 m_deviceCenterFrequency; //!< Center frequency in device
bool m_generation;
@ -71,6 +72,7 @@ private:
std::size_t m_tickCount;
int m_lastEngineState;
MessageQueue m_inputMessageQueue;
SpectrumVis* m_spectrumVis;
void blockApplySettings(bool block) { m_doApplySettings = !block; }
void displaySettings();

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>350</width>
<height>190</height>
<height>400</height>
</rect>
</property>
<property name="sizePolicy">
@ -19,7 +19,7 @@
<property name="minimumSize">
<size>
<width>350</width>
<height>190</height>
<height>400</height>
</size>
</property>
<property name="font">
@ -292,6 +292,35 @@
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="spectrumLayout">
<property name="topMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="GLSpectrum" name="glSpectrum" native="true">
<property name="minimumSize">
<size>
<width>200</width>
<height>200</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"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="padLayout">
<item>
@ -323,6 +352,18 @@
<extends>QToolButton</extends>
<header>gui/buttonswitch.h</header>
</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

@ -25,6 +25,7 @@
#include "util/simpleserializer.h"
#include "dsp/dspcommands.h"
#include "dsp/dspengine.h"
#include "dsp/basebandsamplesink.h"
#include "device/deviceapi.h"
@ -39,7 +40,8 @@ TestSinkOutput::TestSinkOutput(DeviceAPI *deviceAPI) :
m_settings(),
m_testSinkThread(nullptr),
m_deviceDescription("TestSink"),
m_masterTimer(deviceAPI->getMasterTimer())
m_masterTimer(deviceAPI->getMasterTimer()),
m_spectrumSink(nullptr)
{
m_deviceAPI->setNbSinkStreams(1);
}
@ -65,6 +67,7 @@ bool TestSinkOutput::start()
qDebug() << "TestSinkOutput::start";
m_testSinkThread = new TestSinkThread(&m_sampleSourceFifo);
m_testSinkThread->setSpectrumSink(m_spectrumSink);
m_testSinkThread->setSamplerate(m_settings.m_sampleRate);
m_testSinkThread->setLog2Interpolation(m_settings.m_log2Interp);
m_testSinkThread->connectTimer(m_masterTimer);

View File

@ -29,6 +29,7 @@
class TestSinkThread;
class DeviceAPI;
class BasebandSampleSink;
class TestSinkOutput : public DeviceSampleSink {
public:
@ -103,6 +104,8 @@ public:
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
void setSpectrumSink(BasebandSampleSink* spectrumSink) { m_spectrumSink = spectrumSink; }
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
@ -111,6 +114,7 @@ private:
TestSinkThread* m_testSinkThread;
QString m_deviceDescription;
const QTimer& m_masterTimer;
BasebandSampleSink* m_spectrumSink;
void applySettings(const TestSinkSettings& settings, bool force = false);
};

View File

@ -16,6 +16,7 @@
///////////////////////////////////////////////////////////////////////////////////
#include "util/simpleserializer.h"
#include "settings/serializable.h"
#include "testsinksettings.h"
TestSinkSettings::TestSinkSettings()
@ -28,14 +29,20 @@ void TestSinkSettings::resetToDefaults()
m_centerFrequency = 435000*1000;
m_sampleRate = 48000;
m_log2Interp = 0;
m_spectrumGUI = nullptr;
}
QByteArray TestSinkSettings::serialize() const
{
SimpleSerializer s(1);
s.writeU64(1, m_sampleRate);
s.writeU32(2, m_log2Interp);
s.writeU64(1, m_centerFrequency);
s.writeU64(2, m_sampleRate);
s.writeU32(3, m_log2Interp);
if (m_spectrumGUI) {
s.writeBlob(4, m_spectrumGUI->serialize());
}
return s.final();
}
@ -52,8 +59,18 @@ bool TestSinkSettings::deserialize(const QByteArray& data)
if (d.getVersion() == 1)
{
d.readU64(1, &m_sampleRate, 48000);
d.readU32(2, &m_log2Interp, 0);
QByteArray bytetmp;
d.readU64(1, &m_sampleRate, 435000*1000);
d.readU64(2, &m_sampleRate, 48000);
d.readU32(3, &m_log2Interp, 0);
if (m_spectrumGUI)
{
d.readBlob(4, &bytetmp);
m_spectrumGUI->deserialize(bytetmp);
}
return true;
}
else

View File

@ -20,15 +20,19 @@
#include <QByteArray>
class Serializable;
struct TestSinkSettings {
quint64 m_centerFrequency;
quint64 m_sampleRate;
quint32 m_log2Interp;
Serializable *m_spectrumGUI;
TestSinkSettings();
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
void setSpectrumGUI(Serializable *spectrumGUI) { m_spectrumGUI = spectrumGUI; }
};
#endif /* PLUGINS_SAMPLESINK_TESTSINK_TESTSINKSETTINGS_H_ */

View File

@ -22,6 +22,7 @@
#include <QDebug>
#include "dsp/samplesourcefifo.h"
#include "dsp/basebandsamplesink.h"
#include "testsinkthread.h"
TestSinkThread::TestSinkThread(SampleSourceFifo* sampleFifo, QObject* parent) :
@ -177,6 +178,7 @@ void TestSinkThread::tick()
if (m_log2Interpolation == 0)
{
m_interpolators.interpolate1(&beginRead, m_buf, 2*chunkSize);
feedSpectrum(m_buf, 2*chunkSize);
//m_ofstream->write(reinterpret_cast<char*>(&(*beginRead)), m_samplesChunkSize*sizeof(Sample));
}
else
@ -206,7 +208,29 @@ void TestSinkThread::tick()
break;
}
feedSpectrum(m_buf, 2*chunkSize*(1<<m_log2Interpolation));
//m_ofstream->write(reinterpret_cast<char*>(m_buf), m_samplesChunkSize*(1<<m_log2Interpolation)*2*sizeof(int16_t));
}
}
}
void TestSinkThread::feedSpectrum(int16_t *buf, unsigned int bufSize)
{
if (!m_spectrumSink) {
return;
}
m_samplesVector.allocate(bufSize/2);
Sample16 *s16Buf = (Sample16*) buf;
std::transform(
s16Buf,
s16Buf + (bufSize/2),
m_samplesVector.m_vector.begin(),
[](Sample16 s) -> Sample {
return Sample{s.m_real, s.m_imag};
}
);
m_spectrumSink->feed(m_samplesVector.m_vector.begin(), m_samplesVector.m_vector.begin() + (bufSize/2), false);
}

View File

@ -30,10 +30,12 @@
#include "dsp/inthalfbandfilter.h"
#include "dsp/interpolators.h"
#include "util/incrementalvector.h"
#define TESTSINK_THROTTLE_MS 50
class SampleSourceFifo;
class BasebandSampleSink;
class TestSinkThread : public QThread {
Q_OBJECT
@ -50,10 +52,18 @@ public:
bool isRunning() const { return m_running; }
std::size_t getSamplesCount() const { return m_samplesCount; }
void setSamplesCount(int samplesCount) { m_samplesCount = samplesCount; }
void setSpectrumSink(BasebandSampleSink *spectrumSink) { m_spectrumSink = spectrumSink; }
void connectTimer(const QTimer& timer);
private:
#pragma pack(push, 1)
struct Sample16
{
int16_t m_real;
int16_t m_imag;
};
#pragma pack(pop)
QMutex m_startWaitMutex;
QWaitCondition m_startWaiter;
volatile bool m_running;
@ -72,8 +82,11 @@ private:
Interpolators<qint16, SDR_TX_SAMP_SZ, 16> m_interpolators;
int16_t *m_buf;
BasebandSampleSink* m_spectrumSink;
IncrementalVector<Sample> m_samplesVector;
void run();
void feedSpectrum(int16_t *buf, unsigned int bufSize);
private slots:
void tick();