1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-09-04 14:17:50 -04:00

Update threading to latest approach

This commit is contained in:
srcejon 2023-09-29 08:42:25 +01:00
parent 2192a054ed
commit 7fe7f2aa86
7 changed files with 105 additions and 79 deletions

View File

@ -63,6 +63,8 @@ const char * const FreqScanner::m_channelId = "FreqScanner";
FreqScanner::FreqScanner(DeviceAPI *deviceAPI) : FreqScanner::FreqScanner(DeviceAPI *deviceAPI) :
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink),
m_deviceAPI(deviceAPI), m_deviceAPI(deviceAPI),
m_thread(nullptr),
m_basebandSink(nullptr),
m_running(false), m_running(false),
m_basebandSampleRate(0), m_basebandSampleRate(0),
m_scanDeviceSetIndex(-1), m_scanDeviceSetIndex(-1),
@ -72,11 +74,6 @@ FreqScanner::FreqScanner(DeviceAPI *deviceAPI) :
{ {
setObjectName(m_channelId); setObjectName(m_channelId);
m_basebandSink = new FreqScannerBaseband(this);
m_basebandSink->setMessageQueueToChannel(getInputMessageQueue());
m_basebandSink->setChannel(this);
m_basebandSink->moveToThread(&m_thread);
applySettings(m_settings, QStringList(), true); applySettings(m_settings, QStringList(), true);
m_deviceAPI->addChannelSink(this); m_deviceAPI->addChannelSink(this);
@ -96,6 +93,8 @@ FreqScanner::FreqScanner(DeviceAPI *deviceAPI) :
&FreqScanner::handleIndexInDeviceSetChanged &FreqScanner::handleIndexInDeviceSetChanged
); );
start();
scanAvailableChannels(); scanAvailableChannels();
QObject::connect( QObject::connect(
MainCore::instance(), MainCore::instance(),
@ -126,11 +125,7 @@ FreqScanner::~FreqScanner()
m_deviceAPI->removeChannelSinkAPI(this); m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this); m_deviceAPI->removeChannelSink(this);
if (m_basebandSink->isRunning()) { stop();
stop();
}
delete m_basebandSink;
} }
void FreqScanner::setDeviceAPI(DeviceAPI *deviceAPI) void FreqScanner::setDeviceAPI(DeviceAPI *deviceAPI)
@ -161,16 +156,38 @@ void FreqScanner::feed(const SampleVector::const_iterator& begin, const SampleVe
void FreqScanner::start() void FreqScanner::start()
{ {
QMutexLocker m_lock(&m_mutex);
if (m_running) { if (m_running) {
return; return;
} }
qDebug("FreqScanner::start"); qDebug("FreqScanner::start");
m_thread = new QThread();
m_basebandSink = new FreqScannerBaseband(this);
m_basebandSink->setFifoLabel(QString("%1 [%2:%3]")
.arg(m_channelId)
.arg(m_deviceAPI->getDeviceSetIndex())
.arg(getIndexInDeviceSet())
);
m_basebandSink->setMessageQueueToChannel(getInputMessageQueue());
m_basebandSink->setChannel(this);
m_basebandSink->moveToThread(m_thread);
m_basebandSink->reset(); QObject::connect(
m_basebandSink->startWork(); m_thread,
m_thread.start(); &QThread::finished,
// FIXME: Threading!! Compare to SSB m_basebandSink,
&QObject::deleteLater
);
QObject::connect(
m_thread,
&QThread::finished,
m_thread,
&QThread::deleteLater
);
m_thread->start();
DSPSignalNotification *dspMsg = new DSPSignalNotification(m_basebandSampleRate, m_centerFrequency); DSPSignalNotification *dspMsg = new DSPSignalNotification(m_basebandSampleRate, m_centerFrequency);
m_basebandSink->getInputMessageQueue()->push(dspMsg); m_basebandSink->getInputMessageQueue()->push(dspMsg);
@ -183,15 +200,16 @@ void FreqScanner::start()
void FreqScanner::stop() void FreqScanner::stop()
{ {
QMutexLocker m_lock(&m_mutex);
if (!m_running) { if (!m_running) {
return; return;
} }
qDebug("FreqScanner::stop"); qDebug("FreqScanner::stop");
m_running = false; m_running = false;
m_basebandSink->stopWork(); m_thread->exit();
m_thread.quit(); m_thread->wait();
m_thread.wait();
} }
bool FreqScanner::handleMessage(const Message& cmd) bool FreqScanner::handleMessage(const Message& cmd)
@ -314,17 +332,20 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
} }
qSort(frequencies); qSort(frequencies);
// Calculate how many channels can be scanned in one go if ((frequencies.size() > 0) && (m_settings.m_channelBandwidth > 0) && (m_basebandSampleRate > 0))
int fftSize; {
int binsPerChannel; // Calculate how many channels can be scanned in one go
FreqScanner::calcScannerSampleRate(m_settings.m_channelBandwidth, m_basebandSampleRate, m_scannerSampleRate, fftSize, binsPerChannel); int fftSize;
int binsPerChannel;
FreqScanner::calcScannerSampleRate(m_settings.m_channelBandwidth, m_basebandSampleRate, m_scannerSampleRate, fftSize, binsPerChannel);
// Align first frequency so we cover as many channels as possible, while avoiding DC bin // Align first frequency so we cover as many channels as possible, while avoiding DC bin
m_stepStartFrequency = frequencies.front() + m_scannerSampleRate / 2 - m_settings.m_channelBandwidth + m_settings.m_channelBandwidth / 2; m_stepStartFrequency = frequencies.front() + m_scannerSampleRate / 2 - m_settings.m_channelBandwidth + m_settings.m_channelBandwidth / 2;
m_stepStopFrequency = frequencies.back(); m_stepStopFrequency = frequencies.back();
qInfo() << "START_SCAN: Scanning from " << frequencies.front() << "to" << frequencies.back(); qInfo() << "START_SCAN: Scanning from " << frequencies.front() << "to" << frequencies.back();
initScan(); initScan();
}
} }
break; break;
@ -335,19 +356,36 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
m_scanResults.append(results); m_scanResults.append(results);
} }
// Calculate next center frequency
bool complete = false; // Have all frequencies been scanned? bool complete = false; // Have all frequencies been scanned?
bool freqInRange = false;
qint64 nextCenterFrequency = m_centerFrequency; qint64 nextCenterFrequency = m_centerFrequency;
do
{
if (nextCenterFrequency + m_scannerSampleRate / 2 > m_stepStopFrequency)
{
nextCenterFrequency = m_stepStartFrequency;
complete = true;
}
else
{
nextCenterFrequency += m_scannerSampleRate;
complete = false;
}
if (m_stepStopFrequency < m_centerFrequency + m_scannerSampleRate / 2) // Are any frequencies in this new range?
{ for (int i = 0; i < m_settings.m_frequencies.size(); i++)
nextCenterFrequency = m_stepStartFrequency; {
complete = true; if (m_settings.m_enabled[i]
} && (m_settings.m_frequencies[i] >= nextCenterFrequency - m_scannerSampleRate / 2)
else && (m_settings.m_frequencies[i] < nextCenterFrequency + m_scannerSampleRate / 2))
{ {
nextCenterFrequency = m_centerFrequency + m_scannerSampleRate; freqInRange = true;
complete = false; break;
}
}
} }
while (!complete && !freqInRange);
if (complete) if (complete)
{ {

View File

@ -372,8 +372,9 @@ public:
private: private:
DeviceAPI *m_deviceAPI; DeviceAPI *m_deviceAPI;
QThread m_thread; QThread *m_thread;
FreqScannerBaseband* m_basebandSink; FreqScannerBaseband* m_basebandSink;
QRecursiveMutex m_mutex;
bool m_running; bool m_running;
FreqScannerSettings m_settings; FreqScannerSettings m_settings;
int m_basebandSampleRate; //!< stored from device message used when starting baseband sink int m_basebandSampleRate; //!< stored from device message used when starting baseband sink

View File

@ -18,7 +18,7 @@
#include "freqscanneraddrangedialog.h" #include "freqscanneraddrangedialog.h"
#include "ui_freqscanneraddrangedialog.h" #include "ui_freqscanneraddrangedialog.h"
FreqScannerAddRangeDialog::FreqScannerAddRangeDialog(QWidget* parent) : FreqScannerAddRangeDialog::FreqScannerAddRangeDialog(int step, QWidget* parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::FreqScannerAddRangeDialog) ui(new Ui::FreqScannerAddRangeDialog)
{ {
@ -32,6 +32,8 @@ FreqScannerAddRangeDialog::FreqScannerAddRangeDialog(QWidget* parent) :
// Airband frequency range // Airband frequency range
ui->start->setValue(118000000); ui->start->setValue(118000000);
ui->stop->setValue(137000000); ui->stop->setValue(137000000);
ui->step->setCurrentText(QString::number(step));
} }
FreqScannerAddRangeDialog::~FreqScannerAddRangeDialog() FreqScannerAddRangeDialog::~FreqScannerAddRangeDialog()
@ -43,6 +45,6 @@ void FreqScannerAddRangeDialog::accept()
{ {
m_start = ui->start->getValue(); m_start = ui->start->getValue();
m_stop = ui->stop->getValue(); m_stop = ui->stop->getValue();
m_step = ui->step->currentText().toLongLong(); m_step = ui->step->currentText().toInt();
QDialog::accept(); QDialog::accept();
} }

View File

@ -27,7 +27,7 @@ namespace Ui {
class FreqScannerAddRangeDialog : public QDialog { class FreqScannerAddRangeDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit FreqScannerAddRangeDialog(QWidget* parent = nullptr); explicit FreqScannerAddRangeDialog(int step, QWidget* parent = nullptr);
~FreqScannerAddRangeDialog(); ~FreqScannerAddRangeDialog();
qint64 m_start; qint64 m_start;

View File

@ -29,15 +29,25 @@ MESSAGE_CLASS_DEFINITION(FreqScannerBaseband::MsgConfigureFreqScannerBaseband, M
FreqScannerBaseband::FreqScannerBaseband(FreqScanner *freqScanner) : FreqScannerBaseband::FreqScannerBaseband(FreqScanner *freqScanner) :
m_sink(freqScanner), m_sink(freqScanner),
m_messageQueueToGUI(nullptr), m_messageQueueToGUI(nullptr)
m_running(false)
{ {
qDebug("FreqScannerBaseband::FreqScannerBaseband"); qDebug("FreqScannerBaseband::FreqScannerBaseband");
m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000)); m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000));
QObject::connect(
&m_sampleFifo,
&SampleSinkFifo::dataReady,
this,
&FreqScannerBaseband::handleData,
Qt::QueuedConnection
);
m_channelizer = new DownChannelizer(&m_sink); m_channelizer = new DownChannelizer(&m_sink);
m_channelSampleRate = 0; m_channelSampleRate = 0;
m_scannerSampleRate = 0; m_scannerSampleRate = 0;
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
} }
FreqScannerBaseband::~FreqScannerBaseband() FreqScannerBaseband::~FreqScannerBaseband()
@ -54,33 +64,6 @@ void FreqScannerBaseband::reset()
m_channelSampleRate = 0; m_channelSampleRate = 0;
} }
void FreqScannerBaseband::startWork()
{
QMutexLocker mutexLocker(&m_mutex);
QObject::connect(
&m_sampleFifo,
&SampleSinkFifo::dataReady,
this,
&FreqScannerBaseband::handleData,
Qt::QueuedConnection
);
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
m_running = true;
}
void FreqScannerBaseband::stopWork()
{
QMutexLocker mutexLocker(&m_mutex);
disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
QObject::disconnect(
&m_sampleFifo,
&SampleSinkFifo::dataReady,
this,
&FreqScannerBaseband::handleData
);
m_running = false;
}
void FreqScannerBaseband::setChannel(ChannelAPI *channel) void FreqScannerBaseband::setChannel(ChannelAPI *channel)
{ {
m_sink.setChannel(channel); m_sink.setChannel(channel);
@ -110,7 +93,7 @@ void FreqScannerBaseband::handleData()
} }
// second part of FIFO data (used when block wraps around) // second part of FIFO data (used when block wraps around)
if(part2begin != part2end) { if (part2begin != part2end) {
m_channelizer->feed(part2begin, part2end); m_channelizer->feed(part2begin, part2end);
} }
@ -164,8 +147,12 @@ bool FreqScannerBaseband::handleMessage(const Message& cmd)
void FreqScannerBaseband::applySettings(const FreqScannerSettings& settings, const QStringList& settingsKeys, bool force) void FreqScannerBaseband::applySettings(const FreqScannerSettings& settings, const QStringList& settingsKeys, bool force)
{ {
if ((settings.m_channelBandwidth != m_settings.m_channelBandwidth) || (settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) { if ((settings.m_channelBandwidth != m_settings.m_channelBandwidth) || (settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force)
calcScannerSampleRate(m_channelizer->getBasebandSampleRate(), settings.m_channelBandwidth, settings.m_inputFrequencyOffset); {
int basebandSampleRate = m_channelizer->getBasebandSampleRate();
if ((basebandSampleRate != 0) && (settings.m_channelBandwidth != 0)) {
calcScannerSampleRate(basebandSampleRate, settings.m_channelBandwidth, settings.m_inputFrequencyOffset);
}
} }
m_sink.applySettings(settings, settingsKeys, force); m_sink.applySettings(settings, settingsKeys, force);
@ -185,7 +172,9 @@ int FreqScannerBaseband::getChannelSampleRate() const
void FreqScannerBaseband::setBasebandSampleRate(int sampleRate) void FreqScannerBaseband::setBasebandSampleRate(int sampleRate)
{ {
m_channelizer->setBasebandSampleRate(sampleRate); m_channelizer->setBasebandSampleRate(sampleRate);
calcScannerSampleRate(sampleRate, m_settings.m_channelBandwidth, m_settings.m_inputFrequencyOffset); if ((sampleRate != 0) && (m_settings.m_channelBandwidth != 0)) {
calcScannerSampleRate(sampleRate, m_settings.m_channelBandwidth, m_settings.m_inputFrequencyOffset);
}
} }
void FreqScannerBaseband::calcScannerSampleRate(int basebandSampleRate, float rfBandwidth, int inputFrequencyOffset) void FreqScannerBaseband::calcScannerSampleRate(int basebandSampleRate, float rfBandwidth, int inputFrequencyOffset)

View File

@ -62,11 +62,9 @@ public:
{ } { }
}; };
FreqScannerBaseband(FreqScanner *packetDemod); FreqScannerBaseband(FreqScanner *freqScanner);
~FreqScannerBaseband(); ~FreqScannerBaseband();
void reset(); void reset();
void startWork();
void stopWork();
void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end); void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
void setMessageQueueToChannel(MessageQueue *messageQueue) { m_sink.setMessageQueueToChannel(messageQueue); } void setMessageQueueToChannel(MessageQueue *messageQueue) { m_sink.setMessageQueueToChannel(messageQueue); }
@ -74,7 +72,6 @@ public:
void setBasebandSampleRate(int sampleRate); void setBasebandSampleRate(int sampleRate);
int getChannelSampleRate() const; int getChannelSampleRate() const;
void setChannel(ChannelAPI *channel); void setChannel(ChannelAPI *channel);
bool isRunning() const { return m_running; }
void setFifoLabel(const QString& label) { m_sampleFifo.setLabel(label); } void setFifoLabel(const QString& label) { m_sampleFifo.setLabel(label); }
private: private:
@ -86,7 +83,6 @@ private:
MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication
MessageQueue *m_messageQueueToGUI; MessageQueue *m_messageQueueToGUI;
FreqScannerSettings m_settings; FreqScannerSettings m_settings;
bool m_running;
QRecursiveMutex m_mutex; QRecursiveMutex m_mutex;
bool handleMessage(const Message& cmd); bool handleMessage(const Message& cmd);

View File

@ -411,7 +411,7 @@ FreqScannerGUI::FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, B
ui->deltaFrequency->setValueRange(true, 7, 0, 9999999); ui->deltaFrequency->setValueRange(true, 7, 0, 9999999);
ui->channelBandwidth->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow)); ui->channelBandwidth->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
ui->channelBandwidth->setValueRange(true, 7, 16, 9999999); ui->channelBandwidth->setValueRange(true, 7, 0, 9999999);
m_channelMarker.setColor(Qt::yellow); m_channelMarker.setColor(Qt::yellow);
m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset); m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
@ -606,7 +606,7 @@ void FreqScannerGUI::on_addSingle_clicked()
void FreqScannerGUI::on_addRange_clicked() void FreqScannerGUI::on_addRange_clicked()
{ {
FreqScannerAddRangeDialog dialog(this); FreqScannerAddRangeDialog dialog(m_settings.m_channelBandwidth, this);
new DialogPositioner(&dialog, false); new DialogPositioner(&dialog, false);
if (dialog.exec()) if (dialog.exec())
{ {