From ab936710ea6f6eb75760aa1e170c958e5b8e96b7 Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 12 Oct 2022 22:38:46 +0200 Subject: [PATCH] AM demod: updated threading model. Part of #1346 --- plugins/channelrx/demodam/amdemod.cpp | 84 ++++++++++--------- plugins/channelrx/demodam/amdemod.h | 6 +- plugins/channelrx/demodam/amdemodbaseband.cpp | 33 ++++---- plugins/channelrx/demodam/amdemodbaseband.h | 4 +- 4 files changed, 67 insertions(+), 60 deletions(-) diff --git a/plugins/channelrx/demodam/amdemod.cpp b/plugins/channelrx/demodam/amdemod.cpp index dbbdda00c..bc2238038 100644 --- a/plugins/channelrx/demodam/amdemod.cpp +++ b/plugins/channelrx/demodam/amdemod.cpp @@ -51,15 +51,13 @@ const int AMDemod::m_udpBlockSize = 512; AMDemod::AMDemod(DeviceAPI *deviceAPI) : ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), m_deviceAPI(deviceAPI), + m_thread(nullptr), + m_basebandSink(nullptr), + m_running(false), m_basebandSampleRate(0), m_lastTs(0) { setObjectName(m_channelId); - - m_basebandSink = new AMDemodBaseband(); - m_basebandSink->setChannel(this); - m_basebandSink->moveToThread(&m_thread); - applySettings(m_settings, true); m_deviceAPI->addChannelSink(this); @@ -72,31 +70,18 @@ AMDemod::AMDemod(DeviceAPI *deviceAPI) : this, &AMDemod::networkManagerFinished ); - // Experimental: - // QObject::connect( - // m_deviceAPI->getSampleSource()->getSampleFifo(), - // &SampleSinkFifo::written, - // this, - // &AMDemod::handleWrittenToFifo - // ); QObject::connect( this, &ChannelAPI::indexInDeviceSetChanged, this, &AMDemod::handleIndexInDeviceSetChanged ); + start(); } AMDemod::~AMDemod() { qDebug("AMDemod::~AMDemod"); - // Experimental: - // QObject::disconnect( - // m_deviceAPI->getSampleSource()->getSampleFifo(), - // &SampleSinkFifo::written, - // this, - // &AMDemod::handleWrittenToFifo - // ); QObject::disconnect( m_networkManager, &QNetworkAccessManager::finished, @@ -106,12 +91,7 @@ AMDemod::~AMDemod() delete m_networkManager; m_deviceAPI->removeChannelSinkAPI(this); m_deviceAPI->removeChannelSink(this); - - if (m_basebandSink->isRunning()) { - stop(); - } - - delete m_basebandSink; + stop(); } void AMDemod::setDeviceAPI(DeviceAPI *deviceAPI) @@ -139,25 +119,42 @@ void AMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector void AMDemod::start() { + if (m_running) { + return; + } + qDebug("AMDemod::start"); + m_thread = new QThread(); + m_basebandSink = new AMDemodBaseband(); + m_basebandSink->setChannel(this); + m_basebandSink->moveToThread(m_thread); + + QObject::connect(m_thread, &QThread::finished, m_basebandSink, &QObject::deleteLater); + QObject::connect(m_thread, &QThread::finished, m_thread, &QThread::deleteLater); m_basebandSink->reset(); m_basebandSink->startWork(); - m_thread.start(); + m_thread->start(); DSPSignalNotification *dspMsg = new DSPSignalNotification(m_basebandSampleRate, m_centerFrequency); m_basebandSink->getInputMessageQueue()->push(dspMsg); AMDemodBaseband::MsgConfigureAMDemodBaseband *msg = AMDemodBaseband::MsgConfigureAMDemodBaseband::create(m_settings, true); m_basebandSink->getInputMessageQueue()->push(msg); + + m_running = true; } void AMDemod::stop() { + if (!m_running) { + return; + } + qDebug("AMDemod::stop"); - m_basebandSink->stopWork(); - m_thread.quit(); - m_thread.wait(); + m_running = false; + m_thread->quit(); + m_thread->wait(); } bool AMDemod::handleMessage(const Message& cmd) @@ -175,10 +172,14 @@ bool AMDemod::handleMessage(const Message& cmd) DSPSignalNotification& notif = (DSPSignalNotification&) cmd; m_basebandSampleRate = notif.getSampleRate(); m_centerFrequency = notif.getCenterFrequency(); - // Forward to the sink - DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy qDebug() << "AMDemod::handleMessage: DSPSignalNotification"; - m_basebandSink->getInputMessageQueue()->push(rep); + + // Forward to the sink + if (m_running) + { + DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy + m_basebandSink->getInputMessageQueue()->push(rep); + } if (getMessageQueueToGUI()) { getMessageQueueToGUI()->push(new DSPSignalNotification(notif)); @@ -284,8 +285,11 @@ void AMDemod::applySettings(const AMDemodSettings& settings, bool force) reverseAPIKeys.append("streamIndex"); } - AMDemodBaseband::MsgConfigureAMDemodBaseband *msg = AMDemodBaseband::MsgConfigureAMDemodBaseband::create(settings, force); - m_basebandSink->getInputMessageQueue()->push(msg); + if (m_running) + { + AMDemodBaseband::MsgConfigureAMDemodBaseband *msg = AMDemodBaseband::MsgConfigureAMDemodBaseband::create(settings, force); + m_basebandSink->getInputMessageQueue()->push(msg); + } if (settings.m_useReverseAPI) { @@ -547,9 +551,13 @@ void AMDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples); response.getAmDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg)); - response.getAmDemodReport()->setSquelch(m_basebandSink->getSquelchOpen() ? 1 : 0); - response.getAmDemodReport()->setAudioSampleRate(m_basebandSink->getAudioSampleRate()); - response.getAmDemodReport()->setChannelSampleRate(m_basebandSink->getChannelSampleRate()); + + if (m_running) + { + response.getAmDemodReport()->setSquelch(m_basebandSink->getSquelchOpen() ? 1 : 0); + response.getAmDemodReport()->setAudioSampleRate(m_basebandSink->getAudioSampleRate()); + response.getAmDemodReport()->setChannelSampleRate(m_basebandSink->getChannelSampleRate()); + } } void AMDemod::webapiReverseSendSettings(QList& channelSettingsKeys, const AMDemodSettings& settings, bool force) @@ -705,7 +713,7 @@ void AMDemod::handleWrittenToFifo(int nsamples, qint64 timestamp) void AMDemod::handleIndexInDeviceSetChanged(int index) { - if (index < 0) { + if (!m_running || (index < 0)) { return; } diff --git a/plugins/channelrx/demodam/amdemod.h b/plugins/channelrx/demodam/amdemod.h index ed1d49561..3df4148a9 100644 --- a/plugins/channelrx/demodam/amdemod.h +++ b/plugins/channelrx/demodam/amdemod.h @@ -21,7 +21,6 @@ #include #include -#include #include "dsp/basebandsamplesink.h" #include "channel/channelapi.h" @@ -137,8 +136,9 @@ public: private: DeviceAPI *m_deviceAPI; - QThread m_thread; - AMDemodBaseband* m_basebandSink; + QThread *m_thread; + AMDemodBaseband *m_basebandSink; + bool m_running; AMDemodSettings m_settings; int m_basebandSampleRate; //!< stored from device message used when starting baseband sink qint64 m_centerFrequency; diff --git a/plugins/channelrx/demodam/amdemodbaseband.cpp b/plugins/channelrx/demodam/amdemodbaseband.cpp index 5f840095a..41a25490b 100644 --- a/plugins/channelrx/demodam/amdemodbaseband.cpp +++ b/plugins/channelrx/demodam/amdemodbaseband.cpp @@ -26,12 +26,12 @@ MESSAGE_CLASS_DEFINITION(AMDemodBaseband::MsgConfigureAMDemodBaseband, Message) AMDemodBaseband::AMDemodBaseband() : + m_channelizer(&m_sink), m_running(false) { qDebug("AMDemodBaseband::AMDemodBaseband"); m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000)); - m_channelizer = new DownChannelizer(&m_sink); DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue()); m_sink.applyAudioSampleRate(DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate()); @@ -42,7 +42,6 @@ AMDemodBaseband::~AMDemodBaseband() { m_inputMessageQueue.clear(); DSPEngine::instance()->getAudioDeviceManager()->removeAudioSink(m_sink.getAudioFifo()); - delete m_channelizer; } void AMDemodBaseband::reset() @@ -105,12 +104,12 @@ void AMDemodBaseband::handleData() // first part of FIFO data if (part1begin != part1end) { - m_channelizer->feed(part1begin, part1end); + m_channelizer.feed(part1begin, part1end); } // second part of FIFO data (used when block wraps around) if(part2begin != part2end) { - m_channelizer->feed(part2begin, part2end); + m_channelizer.feed(part2begin, part2end); } m_sampleFifo.readCommit((unsigned int) count); @@ -147,13 +146,13 @@ bool AMDemodBaseband::handleMessage(const Message& cmd) DSPSignalNotification& notif = (DSPSignalNotification&) cmd; qDebug() << "AMDemodBaseband::handleMessage: DSPSignalNotification: basebandSampleRate: " << notif.getSampleRate(); m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(notif.getSampleRate())); - m_channelizer->setBasebandSampleRate(notif.getSampleRate()); - m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset()); + m_channelizer.setBasebandSampleRate(notif.getSampleRate()); + m_sink.applyChannelSettings(m_channelizer.getChannelSampleRate(), m_channelizer.getChannelFrequencyOffset()); - if (m_channelSampleRate != m_channelizer->getChannelSampleRate()) + if (m_channelSampleRate != m_channelizer.getChannelSampleRate()) { m_sink.applyAudioSampleRate(m_sink.getAudioSampleRate()); // reapply when channel sample rate changes - m_channelSampleRate = m_channelizer->getChannelSampleRate(); + m_channelSampleRate = m_channelizer.getChannelSampleRate(); } return true; @@ -168,13 +167,13 @@ void AMDemodBaseband::applySettings(const AMDemodSettings& settings, bool force) { if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) { - m_channelizer->setChannelization(m_sink.getAudioSampleRate(), settings.m_inputFrequencyOffset); - m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset()); + m_channelizer.setChannelization(m_sink.getAudioSampleRate(), settings.m_inputFrequencyOffset); + m_sink.applyChannelSettings(m_channelizer.getChannelSampleRate(), m_channelizer.getChannelFrequencyOffset()); - if (m_channelSampleRate != m_channelizer->getChannelSampleRate()) + if (m_channelSampleRate != m_channelizer.getChannelSampleRate()) { m_sink.applyAudioSampleRate(m_sink.getAudioSampleRate()); // reapply when channel sample rate changes - m_channelSampleRate = m_channelizer->getChannelSampleRate(); + m_channelSampleRate = m_channelizer.getChannelSampleRate(); } } @@ -189,8 +188,8 @@ void AMDemodBaseband::applySettings(const AMDemodSettings& settings, bool force) if (m_sink.getAudioSampleRate() != audioSampleRate) { - m_channelizer->setChannelization(audioSampleRate, settings.m_inputFrequencyOffset); - m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset()); + m_channelizer.setChannelization(audioSampleRate, settings.m_inputFrequencyOffset); + m_sink.applyChannelSettings(m_channelizer.getChannelSampleRate(), m_channelizer.getChannelFrequencyOffset()); m_sink.applyAudioSampleRate(audioSampleRate); } } @@ -202,12 +201,12 @@ void AMDemodBaseband::applySettings(const AMDemodSettings& settings, bool force) int AMDemodBaseband::getChannelSampleRate() const { - return m_channelizer->getChannelSampleRate(); + return m_channelizer.getChannelSampleRate(); } void AMDemodBaseband::setBasebandSampleRate(int sampleRate) { - m_channelizer->setBasebandSampleRate(sampleRate); - m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset()); + m_channelizer.setBasebandSampleRate(sampleRate); + m_sink.applyChannelSettings(m_channelizer.getChannelSampleRate(), m_channelizer.getChannelFrequencyOffset()); } diff --git a/plugins/channelrx/demodam/amdemodbaseband.h b/plugins/channelrx/demodam/amdemodbaseband.h index 9df22e007..ebd9cb508 100644 --- a/plugins/channelrx/demodam/amdemodbaseband.h +++ b/plugins/channelrx/demodam/amdemodbaseband.h @@ -22,12 +22,12 @@ #include #include "dsp/samplesinkfifo.h" +#include "dsp/downchannelizer.h" #include "util/message.h" #include "util/messagequeue.h" #include "amdemodsink.h" -class DownChannelizer; class ChannelAPI; class AMDemodBaseband : public QObject @@ -79,7 +79,7 @@ public: private: SampleSinkFifo m_sampleFifo; - DownChannelizer *m_channelizer; + DownChannelizer m_channelizer; int m_channelSampleRate; AMDemodSink m_sink; MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication