mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-22 16:08:39 -05:00
TestSink spectrum display
This commit is contained in:
parent
077a083336
commit
dce1951e94
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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"/>
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
}
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user