From 7fe7f2aa868ac19973cbf3cdcf24123b34b530bb Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 29 Sep 2023 08:42:25 +0100 Subject: [PATCH] Update threading to latest approach --- plugins/channelrx/freqscanner/freqscanner.cpp | 108 ++++++++++++------ plugins/channelrx/freqscanner/freqscanner.h | 3 +- .../freqscanner/freqscanneraddrangedialog.cpp | 6 +- .../freqscanner/freqscanneraddrangedialog.h | 2 +- .../freqscanner/freqscannerbaseband.cpp | 55 ++++----- .../freqscanner/freqscannerbaseband.h | 6 +- .../channelrx/freqscanner/freqscannergui.cpp | 4 +- 7 files changed, 105 insertions(+), 79 deletions(-) diff --git a/plugins/channelrx/freqscanner/freqscanner.cpp b/plugins/channelrx/freqscanner/freqscanner.cpp index 38b36a106..42c00a2b6 100644 --- a/plugins/channelrx/freqscanner/freqscanner.cpp +++ b/plugins/channelrx/freqscanner/freqscanner.cpp @@ -63,6 +63,8 @@ const char * const FreqScanner::m_channelId = "FreqScanner"; FreqScanner::FreqScanner(DeviceAPI *deviceAPI) : ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), m_deviceAPI(deviceAPI), + m_thread(nullptr), + m_basebandSink(nullptr), m_running(false), m_basebandSampleRate(0), m_scanDeviceSetIndex(-1), @@ -72,11 +74,6 @@ FreqScanner::FreqScanner(DeviceAPI *deviceAPI) : { 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); m_deviceAPI->addChannelSink(this); @@ -96,6 +93,8 @@ FreqScanner::FreqScanner(DeviceAPI *deviceAPI) : &FreqScanner::handleIndexInDeviceSetChanged ); + start(); + scanAvailableChannels(); QObject::connect( MainCore::instance(), @@ -126,11 +125,7 @@ FreqScanner::~FreqScanner() m_deviceAPI->removeChannelSinkAPI(this); m_deviceAPI->removeChannelSink(this); - if (m_basebandSink->isRunning()) { - stop(); - } - - delete m_basebandSink; + stop(); } void FreqScanner::setDeviceAPI(DeviceAPI *deviceAPI) @@ -161,16 +156,38 @@ void FreqScanner::feed(const SampleVector::const_iterator& begin, const SampleVe void FreqScanner::start() { + QMutexLocker m_lock(&m_mutex); + if (m_running) { return; } 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(); - m_basebandSink->startWork(); - m_thread.start(); - // FIXME: Threading!! Compare to SSB + QObject::connect( + m_thread, + &QThread::finished, + 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); m_basebandSink->getInputMessageQueue()->push(dspMsg); @@ -183,15 +200,16 @@ void FreqScanner::start() void FreqScanner::stop() { + QMutexLocker m_lock(&m_mutex); + if (!m_running) { return; } qDebug("FreqScanner::stop"); m_running = false; - m_basebandSink->stopWork(); - m_thread.quit(); - m_thread.wait(); + m_thread->exit(); + m_thread->wait(); } bool FreqScanner::handleMessage(const Message& cmd) @@ -314,17 +332,20 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList< } qSort(frequencies); - // Calculate how many channels can be scanned in one go - int fftSize; - int binsPerChannel; - FreqScanner::calcScannerSampleRate(m_settings.m_channelBandwidth, m_basebandSampleRate, m_scannerSampleRate, fftSize, binsPerChannel); + if ((frequencies.size() > 0) && (m_settings.m_channelBandwidth > 0) && (m_basebandSampleRate > 0)) + { + // Calculate how many channels can be scanned in one go + 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 - m_stepStartFrequency = frequencies.front() + m_scannerSampleRate / 2 - m_settings.m_channelBandwidth + m_settings.m_channelBandwidth / 2; - m_stepStopFrequency = frequencies.back(); + // 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_stepStopFrequency = frequencies.back(); - qInfo() << "START_SCAN: Scanning from " << frequencies.front() << "to" << frequencies.back(); - initScan(); + qInfo() << "START_SCAN: Scanning from " << frequencies.front() << "to" << frequencies.back(); + initScan(); + } } break; @@ -335,19 +356,36 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList< m_scanResults.append(results); } + // Calculate next center frequency bool complete = false; // Have all frequencies been scanned? + bool freqInRange = false; 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) - { - nextCenterFrequency = m_stepStartFrequency; - complete = true; - } - else - { - nextCenterFrequency = m_centerFrequency + m_scannerSampleRate; - complete = false; + // Are any frequencies in this new range? + for (int i = 0; i < m_settings.m_frequencies.size(); i++) + { + if (m_settings.m_enabled[i] + && (m_settings.m_frequencies[i] >= nextCenterFrequency - m_scannerSampleRate / 2) + && (m_settings.m_frequencies[i] < nextCenterFrequency + m_scannerSampleRate / 2)) + { + freqInRange = true; + break; + } + } } + while (!complete && !freqInRange); if (complete) { diff --git a/plugins/channelrx/freqscanner/freqscanner.h b/plugins/channelrx/freqscanner/freqscanner.h index ff294b161..85a956a79 100644 --- a/plugins/channelrx/freqscanner/freqscanner.h +++ b/plugins/channelrx/freqscanner/freqscanner.h @@ -372,8 +372,9 @@ public: private: DeviceAPI *m_deviceAPI; - QThread m_thread; + QThread *m_thread; FreqScannerBaseband* m_basebandSink; + QRecursiveMutex m_mutex; bool m_running; FreqScannerSettings m_settings; int m_basebandSampleRate; //!< stored from device message used when starting baseband sink diff --git a/plugins/channelrx/freqscanner/freqscanneraddrangedialog.cpp b/plugins/channelrx/freqscanner/freqscanneraddrangedialog.cpp index afdd7e1e6..c08998641 100644 --- a/plugins/channelrx/freqscanner/freqscanneraddrangedialog.cpp +++ b/plugins/channelrx/freqscanner/freqscanneraddrangedialog.cpp @@ -18,7 +18,7 @@ #include "freqscanneraddrangedialog.h" #include "ui_freqscanneraddrangedialog.h" -FreqScannerAddRangeDialog::FreqScannerAddRangeDialog(QWidget* parent) : +FreqScannerAddRangeDialog::FreqScannerAddRangeDialog(int step, QWidget* parent) : QDialog(parent), ui(new Ui::FreqScannerAddRangeDialog) { @@ -32,6 +32,8 @@ FreqScannerAddRangeDialog::FreqScannerAddRangeDialog(QWidget* parent) : // Airband frequency range ui->start->setValue(118000000); ui->stop->setValue(137000000); + + ui->step->setCurrentText(QString::number(step)); } FreqScannerAddRangeDialog::~FreqScannerAddRangeDialog() @@ -43,6 +45,6 @@ void FreqScannerAddRangeDialog::accept() { m_start = ui->start->getValue(); m_stop = ui->stop->getValue(); - m_step = ui->step->currentText().toLongLong(); + m_step = ui->step->currentText().toInt(); QDialog::accept(); } diff --git a/plugins/channelrx/freqscanner/freqscanneraddrangedialog.h b/plugins/channelrx/freqscanner/freqscanneraddrangedialog.h index 8bacafe7f..7cb25b076 100644 --- a/plugins/channelrx/freqscanner/freqscanneraddrangedialog.h +++ b/plugins/channelrx/freqscanner/freqscanneraddrangedialog.h @@ -27,7 +27,7 @@ namespace Ui { class FreqScannerAddRangeDialog : public QDialog { Q_OBJECT public: - explicit FreqScannerAddRangeDialog(QWidget* parent = nullptr); + explicit FreqScannerAddRangeDialog(int step, QWidget* parent = nullptr); ~FreqScannerAddRangeDialog(); qint64 m_start; diff --git a/plugins/channelrx/freqscanner/freqscannerbaseband.cpp b/plugins/channelrx/freqscanner/freqscannerbaseband.cpp index 1516505f1..8ad6fe125 100644 --- a/plugins/channelrx/freqscanner/freqscannerbaseband.cpp +++ b/plugins/channelrx/freqscanner/freqscannerbaseband.cpp @@ -29,15 +29,25 @@ MESSAGE_CLASS_DEFINITION(FreqScannerBaseband::MsgConfigureFreqScannerBaseband, M FreqScannerBaseband::FreqScannerBaseband(FreqScanner *freqScanner) : m_sink(freqScanner), - m_messageQueueToGUI(nullptr), - m_running(false) + m_messageQueueToGUI(nullptr) { qDebug("FreqScannerBaseband::FreqScannerBaseband"); m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000)); + + QObject::connect( + &m_sampleFifo, + &SampleSinkFifo::dataReady, + this, + &FreqScannerBaseband::handleData, + Qt::QueuedConnection + ); + m_channelizer = new DownChannelizer(&m_sink); m_channelSampleRate = 0; m_scannerSampleRate = 0; + + connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); } FreqScannerBaseband::~FreqScannerBaseband() @@ -54,33 +64,6 @@ void FreqScannerBaseband::reset() 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) { m_sink.setChannel(channel); @@ -110,7 +93,7 @@ void FreqScannerBaseband::handleData() } // second part of FIFO data (used when block wraps around) - if(part2begin != part2end) { + if (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) { - 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); + if ((settings.m_channelBandwidth != m_settings.m_channelBandwidth) || (settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) + { + 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); @@ -185,7 +172,9 @@ int FreqScannerBaseband::getChannelSampleRate() const void FreqScannerBaseband::setBasebandSampleRate(int 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) diff --git a/plugins/channelrx/freqscanner/freqscannerbaseband.h b/plugins/channelrx/freqscanner/freqscannerbaseband.h index 739a2cf8d..f638d7de9 100644 --- a/plugins/channelrx/freqscanner/freqscannerbaseband.h +++ b/plugins/channelrx/freqscanner/freqscannerbaseband.h @@ -62,11 +62,9 @@ public: { } }; - FreqScannerBaseband(FreqScanner *packetDemod); + FreqScannerBaseband(FreqScanner *freqScanner); ~FreqScannerBaseband(); void reset(); - void startWork(); - void stopWork(); void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end); MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication void setMessageQueueToChannel(MessageQueue *messageQueue) { m_sink.setMessageQueueToChannel(messageQueue); } @@ -74,7 +72,6 @@ public: void setBasebandSampleRate(int sampleRate); int getChannelSampleRate() const; void setChannel(ChannelAPI *channel); - bool isRunning() const { return m_running; } void setFifoLabel(const QString& label) { m_sampleFifo.setLabel(label); } private: @@ -86,7 +83,6 @@ private: MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication MessageQueue *m_messageQueueToGUI; FreqScannerSettings m_settings; - bool m_running; QRecursiveMutex m_mutex; bool handleMessage(const Message& cmd); diff --git a/plugins/channelrx/freqscanner/freqscannergui.cpp b/plugins/channelrx/freqscanner/freqscannergui.cpp index 555bec411..71381c03c 100644 --- a/plugins/channelrx/freqscanner/freqscannergui.cpp +++ b/plugins/channelrx/freqscanner/freqscannergui.cpp @@ -411,7 +411,7 @@ FreqScannerGUI::FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, B ui->deltaFrequency->setValueRange(true, 7, 0, 9999999); 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.setCenterFrequency(m_settings.m_inputFrequencyOffset); @@ -606,7 +606,7 @@ void FreqScannerGUI::on_addSingle_clicked() void FreqScannerGUI::on_addRange_clicked() { - FreqScannerAddRangeDialog dialog(this); + FreqScannerAddRangeDialog dialog(m_settings.m_channelBandwidth, this); new DialogPositioner(&dialog, false); if (dialog.exec()) {