mirror of
https://github.com/f4exb/sdrangel.git
synced 2026-08-14 23:43:43 -04:00
TestMOSync: spectrum display
This commit is contained in:
@@ -42,10 +42,13 @@ TestMOSync::TestMOSync(DeviceAPI *deviceAPI) :
|
||||
m_settings(),
|
||||
m_sinkThread(nullptr),
|
||||
m_deviceDescription("TestMOSync"),
|
||||
m_runningTx(false)
|
||||
m_runningTx(false),
|
||||
m_masterTimer(deviceAPI->getMasterTimer()),
|
||||
m_spectrumSink(nullptr),
|
||||
m_feedSpectrumIndex(0)
|
||||
{
|
||||
m_mimoType = MIMOHalfSynchronous;
|
||||
m_sampleMOFifo.init(2, 96000 * 4);
|
||||
m_sampleMOFifo.init(2, 4096*64);
|
||||
m_deviceAPI->setNbSourceStreams(0);
|
||||
m_deviceAPI->setNbSinkStreams(2);
|
||||
}
|
||||
@@ -76,7 +79,11 @@ bool TestMOSync::startTx()
|
||||
m_sampleMOFifo.reset();
|
||||
m_sinkThread->setFifo(&m_sampleMOFifo);
|
||||
m_sinkThread->setFcPos(m_settings.m_fcPosTx);
|
||||
m_sinkThread->setSamplerate(m_settings.m_sampleRate);
|
||||
m_sinkThread->setLog2Interpolation(m_settings.m_log2Interp);
|
||||
m_sinkThread->setSpectrumSink(m_spectrumSink);
|
||||
m_sinkThread->setFeedSpectrumIndex(m_feedSpectrumIndex);
|
||||
m_sinkThread->connectTimer(m_masterTimer);
|
||||
m_sinkThread->startWork();
|
||||
mutexLocker.unlock();
|
||||
m_runningTx = true;
|
||||
@@ -221,6 +228,15 @@ bool TestMOSync::handleMessage(const Message& message)
|
||||
}
|
||||
}
|
||||
|
||||
void TestMOSync::setFeedSpectrumIndex(unsigned int feedSpectrumIndex)
|
||||
{
|
||||
m_feedSpectrumIndex = feedSpectrumIndex > 1 ? 1 : feedSpectrumIndex;
|
||||
|
||||
if (m_sinkThread) {
|
||||
m_sinkThread->setFeedSpectrumIndex(m_feedSpectrumIndex);
|
||||
}
|
||||
}
|
||||
|
||||
bool TestMOSync::applySettings(const TestMOSyncSettings& settings, bool force)
|
||||
{
|
||||
QList<QString> reverseAPIKeys;
|
||||
|
||||
@@ -22,12 +22,14 @@
|
||||
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
#include <QTimer>
|
||||
|
||||
#include "dsp/devicesamplemimo.h"
|
||||
#include "testmosyncsettings.h"
|
||||
|
||||
class DeviceAPI;
|
||||
class TestMOSyncThread;
|
||||
class BasebandSampleSink;
|
||||
|
||||
class TestMOSync : public DeviceSampleMIMO {
|
||||
Q_OBJECT
|
||||
@@ -119,6 +121,8 @@ public:
|
||||
|
||||
bool getRxRunning() const { return false; }
|
||||
bool getTxRunning() const { return m_runningTx; }
|
||||
void setSpectrumSink(BasebandSampleSink* spectrumSink) { m_spectrumSink = spectrumSink; }
|
||||
void setFeedSpectrumIndex(unsigned int feedSpectrumIndex);
|
||||
|
||||
private:
|
||||
DeviceAPI *m_deviceAPI;
|
||||
@@ -127,6 +131,9 @@ private:
|
||||
TestMOSyncThread* m_sinkThread;
|
||||
QString m_deviceDescription;
|
||||
bool m_runningTx;
|
||||
const QTimer& m_masterTimer;
|
||||
BasebandSampleSink* m_spectrumSink;
|
||||
unsigned int m_feedSpectrumIndex;
|
||||
|
||||
bool applySettings(const TestMOSyncSettings& settings, bool force);
|
||||
};
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "gui/glspectrum.h"
|
||||
#include "dsp/dspengine.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
#include "dsp/spectrumvis.h"
|
||||
#include "mainwindow.h"
|
||||
#include "device/deviceapi.h"
|
||||
#include "device/deviceuiset.h"
|
||||
@@ -49,6 +50,7 @@ TestMOSyncGui::TestMOSyncGui(DeviceUISet *deviceUISet, QWidget* parent) :
|
||||
m_lastEngineState(DeviceAPI::StNotStarted)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
m_sampleMIMO = (TestMOSync*) m_deviceUISet->m_deviceAPI->getSampleMIMO();
|
||||
|
||||
ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
||||
ui->centerFrequency->setValueRange(7, 0, pow(10,7));
|
||||
@@ -56,6 +58,13 @@ TestMOSyncGui::TestMOSyncGui(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_sampleMIMO->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,9 +72,12 @@ TestMOSyncGui::TestMOSyncGui(DeviceUISet *deviceUISet, QWidget* parent) :
|
||||
|
||||
displaySettings();
|
||||
|
||||
m_sampleMIMO = (TestMOSync*) m_deviceUISet->m_deviceAPI->getSampleMIMO();
|
||||
m_sampleMIMO->setMessageQueueToGUI(&m_inputMessageQueue);
|
||||
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
|
||||
|
||||
m_deviceUISet->m_spectrum->setDisplayedStream(false, 0);
|
||||
m_deviceUISet->m_deviceAPI->setSpectrumSinkInput(false, 0);
|
||||
m_deviceUISet->setSpectrumScalingFactor(SDR_TX_SCALEF);
|
||||
}
|
||||
|
||||
TestMOSyncGui::~TestMOSyncGui()
|
||||
@@ -114,12 +126,15 @@ QByteArray TestMOSyncGui::serialize() const
|
||||
|
||||
bool TestMOSyncGui::deserialize(const QByteArray& data)
|
||||
{
|
||||
if(m_settings.deserialize(data)) {
|
||||
if (m_settings.deserialize(data))
|
||||
{
|
||||
displaySettings();
|
||||
m_forceSettings = true;
|
||||
sendSettings();
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
@@ -127,7 +142,28 @@ bool TestMOSyncGui::deserialize(const QByteArray& data)
|
||||
|
||||
bool TestMOSyncGui::handleMessage(const Message& message)
|
||||
{
|
||||
if (TestMOSync::MsgConfigureTestMOSync::match(message))
|
||||
if (DSPMIMOSignalNotification::match(message))
|
||||
{
|
||||
const DSPMIMOSignalNotification& cfg = (DSPMIMOSignalNotification&) message;
|
||||
int istream = cfg.getIndex();
|
||||
bool sourceOrSink = cfg.getSourceOrSink();
|
||||
qDebug("TestMOSyncGui::handleMessage: DSPMIMOSignalNotification: %s:%d SampleRate:%d, CenterFrequency:%llu",
|
||||
sourceOrSink ? "Rx" : "Tx",
|
||||
istream,
|
||||
cfg.getSampleRate(),
|
||||
cfg.getCenterFrequency()
|
||||
);
|
||||
|
||||
if (!sourceOrSink)
|
||||
{
|
||||
m_sampleRate = cfg.getSampleRate();
|
||||
m_deviceCenterFrequency = cfg.getCenterFrequency();
|
||||
updateSampleRateAndFrequency();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (TestMOSync::MsgConfigureTestMOSync::match(message))
|
||||
{
|
||||
qDebug("TestMOSyncGui::handleMessage: message: MsgConfigureTestMOSync");
|
||||
const TestMOSync::MsgConfigureTestMOSync& cfg = (TestMOSync::MsgConfigureTestMOSync&) message;
|
||||
@@ -158,24 +194,9 @@ void TestMOSyncGui::handleInputMessages()
|
||||
|
||||
while ((message = m_inputMessageQueue.pop()) != 0)
|
||||
{
|
||||
|
||||
if (DSPSignalNotification::match(*message))
|
||||
{
|
||||
DSPSignalNotification* notif = (DSPSignalNotification*) message;
|
||||
qDebug("TestMOSyncGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->getSampleRate(), notif->getCenterFrequency());
|
||||
m_sampleRate = notif->getSampleRate();
|
||||
m_deviceCenterFrequency = notif->getCenterFrequency();
|
||||
updateSampleRateAndFrequency();
|
||||
|
||||
if (handleMessage(*message)) {
|
||||
delete message;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (handleMessage(*message))
|
||||
{
|
||||
delete message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,20 +222,23 @@ void TestMOSyncGui::sendSettings()
|
||||
|
||||
void TestMOSyncGui::updateHardware()
|
||||
{
|
||||
qDebug() << "TestMOSyncGui::updateHardware";
|
||||
TestMOSync::MsgConfigureTestMOSync* message = TestMOSync::MsgConfigureTestMOSync::create(m_settings, m_forceSettings);
|
||||
m_sampleMIMO->getInputMessageQueue()->push(message);
|
||||
m_forceSettings = false;
|
||||
m_updateTimer.stop();
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
qDebug() << "TestMOSyncGui::updateHardware";
|
||||
TestMOSync::MsgConfigureTestMOSync* message = TestMOSync::MsgConfigureTestMOSync::create(m_settings, m_forceSettings);
|
||||
m_sampleMIMO->getInputMessageQueue()->push(message);
|
||||
m_forceSettings = false;
|
||||
m_updateTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
void TestMOSyncGui::updateStatus()
|
||||
{
|
||||
int state = m_deviceUISet->m_deviceAPI->state();
|
||||
int state = m_deviceUISet->m_deviceAPI->state(1);
|
||||
|
||||
if(m_lastEngineState != state)
|
||||
if (m_lastEngineState != state)
|
||||
{
|
||||
switch(state)
|
||||
switch (state)
|
||||
{
|
||||
case DeviceAPI::StNotStarted:
|
||||
ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
|
||||
@@ -240,12 +264,14 @@ void TestMOSyncGui::updateStatus()
|
||||
void TestMOSyncGui::on_centerFrequency_changed(quint64 value)
|
||||
{
|
||||
m_settings.m_centerFrequency = value * 1000;
|
||||
ui->glSpectrum->setCenterFrequency(m_settings.m_centerFrequency);
|
||||
sendSettings();
|
||||
}
|
||||
|
||||
void TestMOSyncGui::on_sampleRate_changed(quint64 value)
|
||||
{
|
||||
m_settings.m_sampleRate = value;
|
||||
ui->glSpectrum->setSampleRate(m_settings.m_sampleRate*(1<<m_settings.m_log2Interp));
|
||||
sendSettings();
|
||||
}
|
||||
|
||||
@@ -256,6 +282,7 @@ void TestMOSyncGui::on_interp_currentIndexChanged(int index)
|
||||
}
|
||||
|
||||
m_settings.m_log2Interp = index;
|
||||
ui->glSpectrum->setSampleRate(m_settings.m_sampleRate*(1<<m_settings.m_log2Interp));
|
||||
updateSampleRateAndFrequency();
|
||||
sendSettings();
|
||||
}
|
||||
@@ -269,6 +296,13 @@ void TestMOSyncGui::on_startStop_toggled(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
void TestMOSyncGui::on_spectrumIndex_currentIndexChanged(int index)
|
||||
{
|
||||
m_deviceUISet->m_spectrum->setDisplayedStream(false, index);
|
||||
m_deviceUISet->m_deviceAPI->setSpectrumSinkInput(false, index);
|
||||
m_sampleMIMO->setFeedSpectrumIndex(index);
|
||||
}
|
||||
|
||||
void TestMOSyncGui::tick()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
class DeviceUISet;
|
||||
class TestMOSync;
|
||||
class SpectrumVis;
|
||||
|
||||
namespace Ui {
|
||||
class TestMOSyncGui;
|
||||
@@ -70,6 +71,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();
|
||||
@@ -82,6 +84,7 @@ private slots:
|
||||
void on_sampleRate_changed(quint64 value);
|
||||
void on_startStop_toggled(bool checked);
|
||||
void on_interp_currentIndexChanged(int index);
|
||||
void on_spectrumIndex_currentIndexChanged(int index);
|
||||
void updateHardware();
|
||||
void updateStatus();
|
||||
void tick();
|
||||
|
||||
@@ -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">
|
||||
@@ -182,6 +182,39 @@
|
||||
<property name="topMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="spectrumLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../../sdrgui/resources/res.qrc">:/dsb.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="spectrumIndex">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>35</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Select which stream index to display spectrum</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="interpLabel">
|
||||
<property name="text">
|
||||
@@ -292,6 +325,29 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="spectrumLayout">
|
||||
<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 +379,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"/>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include "dsp/samplemofifo.h"
|
||||
#include "dsp/basebandsamplesink.h"
|
||||
|
||||
#include "testmosyncsettings.h"
|
||||
#include "testmosyncthread.h"
|
||||
@@ -29,10 +30,13 @@ TestMOSyncThread::TestMOSyncThread(QObject* parent) :
|
||||
m_log2Interp(0),
|
||||
m_throttlems(TestMOSyncSettings::m_msThrottle),
|
||||
m_throttleToggle(false),
|
||||
m_samplesRemainder(0)
|
||||
m_blockSize(TestMOSyncSettings::m_blockSize),
|
||||
m_samplesRemainder(0),
|
||||
m_feedSpectrumIndex(0),
|
||||
m_spectrumSink(nullptr)
|
||||
{
|
||||
qDebug("TestMOSyncThread::TestMOSyncThread");
|
||||
m_buf = new qint16[2*TestMOSyncSettings::m_blockSize*2];
|
||||
m_buf = new qint16[2*m_blockSize*2];
|
||||
}
|
||||
|
||||
TestMOSyncThread::~TestMOSyncThread()
|
||||
@@ -102,6 +106,9 @@ void TestMOSyncThread::setSamplerate(int samplerate)
|
||||
|
||||
m_samplerate = samplerate;
|
||||
m_samplesChunkSize = (m_samplerate * m_throttlems) / 1000;
|
||||
m_blockSize = (m_samplerate * 50) / 1000;
|
||||
delete[] m_buf;
|
||||
m_buf = new qint16[2*m_blockSize*2];
|
||||
|
||||
if (wasRunning) {
|
||||
startWork();
|
||||
@@ -159,18 +166,18 @@ void TestMOSyncThread::callback(qint16* buf, qint32 samplesPerChannel)
|
||||
|
||||
if (iPart1Begin != iPart1End)
|
||||
{
|
||||
callbackPart(buf, samplesPerChannel, iPart1Begin, iPart1End - iPart1Begin);
|
||||
callbackPart(buf, (iPart1End - iPart1Begin)*(1<<m_log2Interp), iPart1Begin);
|
||||
}
|
||||
|
||||
if (iPart2Begin != iPart2End)
|
||||
{
|
||||
unsigned int part1Size = iPart1End - iPart1End;
|
||||
callbackPart(buf + 2*part1Size, samplesPerChannel, iPart2Begin, iPart2End - iPart2Begin);
|
||||
unsigned int shift = (iPart1End - iPart1Begin)*(1<<m_log2Interp);
|
||||
callbackPart(buf + 2*shift, (iPart2End - iPart2Begin)*(1<<m_log2Interp), iPart2Begin);
|
||||
}
|
||||
}
|
||||
|
||||
// Interpolate according to specified log2 (ex: log2=4 => decim=16). len is a number of samples (not a number of I or Q)
|
||||
void TestMOSyncThread::callbackPart(qint16* buf, qint32 samplesPerChannel, int iBegin, qint32 nSamples)
|
||||
void TestMOSyncThread::callbackPart(qint16* buf, qint32 nSamples, int iBegin)
|
||||
{
|
||||
for (unsigned int channel = 0; channel < 2; channel++)
|
||||
{
|
||||
@@ -178,7 +185,7 @@ void TestMOSyncThread::callbackPart(qint16* buf, qint32 samplesPerChannel, int i
|
||||
|
||||
if (m_log2Interp == 0)
|
||||
{
|
||||
m_interpolators[channel].interpolate1(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate1(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -187,22 +194,22 @@ void TestMOSyncThread::callbackPart(qint16* buf, qint32 samplesPerChannel, int i
|
||||
switch (m_log2Interp)
|
||||
{
|
||||
case 1:
|
||||
m_interpolators[channel].interpolate2_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate2_inf(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 2:
|
||||
m_interpolators[channel].interpolate4_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate4_inf(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 3:
|
||||
m_interpolators[channel].interpolate8_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate8_inf(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 4:
|
||||
m_interpolators[channel].interpolate16_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate16_inf(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 5:
|
||||
m_interpolators[channel].interpolate32_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate32_inf(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 6:
|
||||
m_interpolators[channel].interpolate64_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate64_inf(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -213,22 +220,22 @@ void TestMOSyncThread::callbackPart(qint16* buf, qint32 samplesPerChannel, int i
|
||||
switch (m_log2Interp)
|
||||
{
|
||||
case 1:
|
||||
m_interpolators[channel].interpolate2_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate2_sup(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 2:
|
||||
m_interpolators[channel].interpolate4_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate4_sup(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 3:
|
||||
m_interpolators[channel].interpolate8_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate8_sup(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 4:
|
||||
m_interpolators[channel].interpolate16_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate16_sup(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 5:
|
||||
m_interpolators[channel].interpolate32_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate32_sup(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 6:
|
||||
m_interpolators[channel].interpolate64_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate64_sup(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -239,28 +246,32 @@ void TestMOSyncThread::callbackPart(qint16* buf, qint32 samplesPerChannel, int i
|
||||
switch (m_log2Interp)
|
||||
{
|
||||
case 1:
|
||||
m_interpolators[channel].interpolate2_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate2_cen(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 2:
|
||||
m_interpolators[channel].interpolate4_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate4_cen(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 3:
|
||||
m_interpolators[channel].interpolate8_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate8_cen(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 4:
|
||||
m_interpolators[channel].interpolate16_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate16_cen(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 5:
|
||||
m_interpolators[channel].interpolate32_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate32_cen(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
case 6:
|
||||
m_interpolators[channel].interpolate64_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
|
||||
m_interpolators[channel].interpolate64_cen(&begin, &buf[channel*2*nSamples], 2*nSamples);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (channel == m_feedSpectrumIndex) {
|
||||
feedSpectrum(&buf[channel*2*nSamples], nSamples*2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,12 +290,33 @@ void TestMOSyncThread::tick()
|
||||
|
||||
int chunkSize = std::min((int) m_samplesChunkSize, m_samplerate) + m_samplesRemainder;
|
||||
|
||||
while (chunkSize >= TestMOSyncSettings::m_blockSize)
|
||||
while (chunkSize >= m_blockSize)
|
||||
{
|
||||
callback(m_buf, TestMOSyncSettings::m_blockSize);
|
||||
chunkSize -= TestMOSyncSettings::m_blockSize;
|
||||
callback(m_buf, m_blockSize);
|
||||
chunkSize -= m_blockSize;
|
||||
}
|
||||
|
||||
m_samplesRemainder = chunkSize;
|
||||
}
|
||||
}
|
||||
|
||||
void TestMOSyncThread::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);
|
||||
}
|
||||
|
||||
@@ -26,11 +26,13 @@
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include "dsp/interpolators.h"
|
||||
#include "util/incrementalvector.h"
|
||||
|
||||
#define TESTMOSYNC_THROTTLE_MS 50
|
||||
|
||||
class QTimer;
|
||||
class SampleMOFifo;
|
||||
class BasebandSampleSink;
|
||||
|
||||
class TestMOSyncThread : public QThread {
|
||||
Q_OBJECT
|
||||
@@ -50,15 +52,24 @@ public:
|
||||
void setFifo(SampleMOFifo *sampleFifo) { m_sampleFifo = sampleFifo; }
|
||||
SampleMOFifo *getFifo() { return m_sampleFifo; }
|
||||
void connectTimer(const QTimer& timer);
|
||||
void setSpectrumSink(BasebandSampleSink *spectrumSink) { m_spectrumSink = spectrumSink; }
|
||||
void setFeedSpectrumIndex(unsigned int feedSpectrumIndex) { m_feedSpectrumIndex = feedSpectrumIndex > 1 ? 1 : feedSpectrumIndex; }
|
||||
|
||||
private:
|
||||
#pragma pack(push, 1)
|
||||
struct Sample16
|
||||
{
|
||||
int16_t m_real;
|
||||
int16_t m_imag;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
QMutex m_startWaitMutex;
|
||||
QWaitCondition m_startWaiter;
|
||||
bool m_running;
|
||||
|
||||
qint16 *m_buf; //!< Full buffer for SISO or MIMO operation
|
||||
SampleMOFifo* m_sampleFifo;
|
||||
Interpolators<qint16, SDR_TX_SAMP_SZ, 12> m_interpolators[2];
|
||||
Interpolators<qint16, SDR_TX_SAMP_SZ, 16> m_interpolators[2];
|
||||
unsigned int m_log2Interp;
|
||||
int m_fcPos;
|
||||
|
||||
@@ -66,13 +77,19 @@ private:
|
||||
QElapsedTimer m_elapsedTimer;
|
||||
bool m_throttleToggle;
|
||||
unsigned int m_samplesChunkSize;
|
||||
unsigned int m_blockSize;
|
||||
unsigned int m_samplesRemainder;
|
||||
int m_samplerate;
|
||||
|
||||
unsigned int m_feedSpectrumIndex;
|
||||
BasebandSampleSink* m_spectrumSink;
|
||||
IncrementalVector<Sample> m_samplesVector;
|
||||
|
||||
void run();
|
||||
unsigned int getNbFifos();
|
||||
void callbackPart(qint16* buf, qint32 samplesPerChannel, int iBegin, qint32 nSamples);
|
||||
void callbackPart(qint16* buf, qint32 nSamples, int iBegin);
|
||||
void callback(qint16* buf, qint32 samplesPerChannel);
|
||||
void feedSpectrum(int16_t *buf, unsigned int bufSize);
|
||||
|
||||
private slots:
|
||||
void tick();
|
||||
|
||||
Reference in New Issue
Block a user