From c9dad594385ea77cf675a922c69a0b0f159540ad Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 12 Oct 2022 22:52:50 +0200 Subject: [PATCH] BFM demod: updated threading model. Part of #1346 --- plugins/channelrx/demodbfm/bfmdemod.cpp | 63 +++++++++++++------ plugins/channelrx/demodbfm/bfmdemod.h | 3 +- .../channelrx/demodbfm/bfmdemodbaseband.cpp | 41 ++++++------ plugins/channelrx/demodbfm/bfmdemodbaseband.h | 4 +- 4 files changed, 69 insertions(+), 42 deletions(-) diff --git a/plugins/channelrx/demodbfm/bfmdemod.cpp b/plugins/channelrx/demodbfm/bfmdemod.cpp index cf2afaea1..3c496aa13 100644 --- a/plugins/channelrx/demodbfm/bfmdemod.cpp +++ b/plugins/channelrx/demodbfm/bfmdemod.cpp @@ -51,17 +51,13 @@ const int BFMDemod::m_udpBlockSize = 512; BFMDemod::BFMDemod(DeviceAPI *deviceAPI) : ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), m_deviceAPI(deviceAPI), + m_thread(nullptr), + m_basebandSink(nullptr), + m_running(false), m_spectrumVis(SDR_RX_SCALEF), m_basebandSampleRate(0) { setObjectName(m_channelId); - - m_thread = new QThread(this); - m_basebandSink = new BFMDemodBaseband(); - m_basebandSink->setSpectrumSink(&m_spectrumVis); - m_basebandSink->setChannel(this); - m_basebandSink->moveToThread(m_thread); - applySettings(m_settings, true); m_deviceAPI->addChannelSink(this); @@ -80,6 +76,8 @@ BFMDemod::BFMDemod(DeviceAPI *deviceAPI) : this, &BFMDemod::handleIndexInDeviceSetChanged ); + + start(); } BFMDemod::~BFMDemod() @@ -94,8 +92,7 @@ BFMDemod::~BFMDemod() m_deviceAPI->removeChannelSinkAPI(this); m_deviceAPI->removeChannelSink(this); - delete m_basebandSink; - delete m_thread; + stop(); } void BFMDemod::setDeviceAPI(DeviceAPI *deviceAPI) @@ -123,7 +120,19 @@ void BFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto void BFMDemod::start() { + if (m_running) { + return; + } + qDebug() << "BFMDemod::start"; + m_thread = new QThread(this); + m_basebandSink = new BFMDemodBaseband(); + m_basebandSink->setSpectrumSink(&m_spectrumVis); + 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); if (m_basebandSampleRate != 0) { m_basebandSink->setBasebandSampleRate(m_basebandSampleRate); @@ -136,11 +145,18 @@ void BFMDemod::start() spectrumSettings.m_ssb = true; SpectrumVis::MsgConfigureSpectrumVis *msg = SpectrumVis::MsgConfigureSpectrumVis::create(spectrumSettings, false); m_spectrumVis.getInputMessageQueue()->push(msg); + + m_running = true; } void BFMDemod::stop() { + if (!m_running) { + return; + } + qDebug() << "BFMDemod::stop"; + m_running = false; m_thread->exit(); m_thread->wait(); } @@ -160,10 +176,14 @@ bool BFMDemod::handleMessage(const Message& cmd) { DSPSignalNotification& notif = (DSPSignalNotification&) cmd; m_basebandSampleRate = notif.getSampleRate(); - // Forward to the sink - DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy qDebug() << "BFMDemod::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)); @@ -253,8 +273,11 @@ void BFMDemod::applySettings(const BFMDemodSettings& settings, bool force) reverseAPIKeys.append("streamIndex"); } - BFMDemodBaseband::MsgConfigureBFMDemodBaseband *msg = BFMDemodBaseband::MsgConfigureBFMDemodBaseband::create(settings, force); - m_basebandSink->getInputMessageQueue()->push(msg); + if (m_running) + { + BFMDemodBaseband::MsgConfigureBFMDemodBaseband *msg = BFMDemodBaseband::MsgConfigureBFMDemodBaseband::create(settings, force); + m_basebandSink->getInputMessageQueue()->push(msg); + } if (settings.m_useReverseAPI) { @@ -512,12 +535,16 @@ void BFMDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples); response.getBfmDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg)); - response.getBfmDemodReport()->setSquelch(m_basebandSink->getSquelchState() > 0 ? 1 : 0); - response.getBfmDemodReport()->setAudioSampleRate(m_basebandSink->getAudioSampleRate()); - response.getBfmDemodReport()->setChannelSampleRate(m_basebandSink->getChannelSampleRate()); response.getBfmDemodReport()->setPilotLocked(getPilotLock() ? 1 : 0); response.getBfmDemodReport()->setPilotPowerDb(CalcDb::dbPower(getPilotLevel())); + if (m_running) + { + response.getBfmDemodReport()->setSquelch(m_basebandSink->getSquelchState() > 0 ? 1 : 0); + response.getBfmDemodReport()->setAudioSampleRate(m_basebandSink->getAudioSampleRate()); + response.getBfmDemodReport()->setChannelSampleRate(m_basebandSink->getChannelSampleRate()); + } + if (m_settings.m_rdsActive) { response.getBfmDemodReport()->setRdsReport(new SWGSDRangel::SWGRDSReport()); @@ -708,7 +735,7 @@ void BFMDemod::networkManagerFinished(QNetworkReply *reply) void BFMDemod::handleIndexInDeviceSetChanged(int index) { - if (index < 0) { + if (!m_running && (index < 0)) { return; } diff --git a/plugins/channelrx/demodbfm/bfmdemod.h b/plugins/channelrx/demodbfm/bfmdemod.h index ccead9535..cf50ac989 100644 --- a/plugins/channelrx/demodbfm/bfmdemod.h +++ b/plugins/channelrx/demodbfm/bfmdemod.h @@ -152,7 +152,8 @@ public: private: DeviceAPI *m_deviceAPI; QThread *m_thread; - BFMDemodBaseband* m_basebandSink; + BFMDemodBaseband *m_basebandSink; + bool m_running; BFMDemodSettings m_settings; SpectrumVis m_spectrumVis; int m_basebandSampleRate; //!< stored from device message used when starting baseband sink diff --git a/plugins/channelrx/demodbfm/bfmdemodbaseband.cpp b/plugins/channelrx/demodbfm/bfmdemodbaseband.cpp index 9c7697fae..37d7242b3 100644 --- a/plugins/channelrx/demodbfm/bfmdemodbaseband.cpp +++ b/plugins/channelrx/demodbfm/bfmdemodbaseband.cpp @@ -28,11 +28,11 @@ MESSAGE_CLASS_DEFINITION(BFMDemodBaseband::MsgConfigureBFMDemodBaseband, Message) BFMDemodBaseband::BFMDemodBaseband() : + m_channelizer(&m_sink), m_messageQueueToGUI(nullptr), m_spectrumVis(nullptr) { m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000)); - m_channelizer = new DownChannelizer(&m_sink); qDebug("BFMDemodBaseband::BFMDemodBaseband"); QObject::connect( @@ -53,7 +53,6 @@ BFMDemodBaseband::BFMDemodBaseband() : BFMDemodBaseband::~BFMDemodBaseband() { DSPEngine::instance()->getAudioDeviceManager()->removeAudioSink(m_sink.getAudioFifo()); - delete m_channelizer; } void BFMDemodBaseband::reset() @@ -88,12 +87,12 @@ void BFMDemodBaseband::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); @@ -130,24 +129,24 @@ bool BFMDemodBaseband::handleMessage(const Message& cmd) DSPSignalNotification& notif = (DSPSignalNotification&) cmd; qDebug() << "BFMDemodBaseband::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(); } if (getMessageQueueToGUI()) { - BFMDemodReport::MsgReportChannelSampleRateChanged *msg = BFMDemodReport::MsgReportChannelSampleRateChanged::create(m_channelizer->getChannelSampleRate()); + BFMDemodReport::MsgReportChannelSampleRateChanged *msg = BFMDemodReport::MsgReportChannelSampleRateChanged::create(m_channelizer.getChannelSampleRate()); getMessageQueueToGUI()->push(msg); } if (m_spectrumVis) { - DSPSignalNotification *msg = new DSPSignalNotification(m_channelizer->getChannelSampleRate(), 0); + DSPSignalNotification *msg = new DSPSignalNotification(m_channelizer.getChannelSampleRate(), 0); m_spectrumVis->getInputMessageQueue()->push(msg); } @@ -164,24 +163,24 @@ void BFMDemodBaseband::applySettings(const BFMDemodSettings& settings, bool forc if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || (settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) { - m_channelizer->setChannelization(BFMDemodSettings::requiredBW(settings.m_rfBandwidth), settings.m_inputFrequencyOffset); - m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset()); + m_channelizer.setChannelization(BFMDemodSettings::requiredBW(settings.m_rfBandwidth), 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 changea - m_channelSampleRate = m_channelizer->getChannelSampleRate(); + m_channelSampleRate = m_channelizer.getChannelSampleRate(); } if (getMessageQueueToGUI()) { - BFMDemodReport::MsgReportChannelSampleRateChanged *msg = BFMDemodReport::MsgReportChannelSampleRateChanged::create(m_channelizer->getChannelSampleRate()); + BFMDemodReport::MsgReportChannelSampleRateChanged *msg = BFMDemodReport::MsgReportChannelSampleRateChanged::create(m_channelizer.getChannelSampleRate()); getMessageQueueToGUI()->push(msg); } if (m_spectrumVis) { - DSPSignalNotification *msg = new DSPSignalNotification(m_channelizer->getChannelSampleRate(), 0); + DSPSignalNotification *msg = new DSPSignalNotification(m_channelizer.getChannelSampleRate(), 0); m_spectrumVis->getInputMessageQueue()->push(msg); } } @@ -207,24 +206,24 @@ void BFMDemodBaseband::applySettings(const BFMDemodSettings& settings, bool forc int BFMDemodBaseband::getChannelSampleRate() const { - return m_channelizer->getChannelSampleRate(); + return m_channelizer.getChannelSampleRate(); } void BFMDemodBaseband::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()); if (getMessageQueueToGUI()) { - BFMDemodReport::MsgReportChannelSampleRateChanged *msg = BFMDemodReport::MsgReportChannelSampleRateChanged::create(m_channelizer->getChannelSampleRate()); + BFMDemodReport::MsgReportChannelSampleRateChanged *msg = BFMDemodReport::MsgReportChannelSampleRateChanged::create(m_channelizer.getChannelSampleRate()); getMessageQueueToGUI()->push(msg); } if (m_spectrumVis) { - DSPSignalNotification *msg = new DSPSignalNotification(m_channelizer->getChannelSampleRate(), 0); + DSPSignalNotification *msg = new DSPSignalNotification(m_channelizer.getChannelSampleRate(), 0); m_spectrumVis->getInputMessageQueue()->push(msg); } } diff --git a/plugins/channelrx/demodbfm/bfmdemodbaseband.h b/plugins/channelrx/demodbfm/bfmdemodbaseband.h index a9d7d9f3b..59279770f 100644 --- a/plugins/channelrx/demodbfm/bfmdemodbaseband.h +++ b/plugins/channelrx/demodbfm/bfmdemodbaseband.h @@ -22,12 +22,12 @@ #include #include "dsp/samplesinkfifo.h" +#include "dsp/downchannelizer.h" #include "util/message.h" #include "util/messagequeue.h" #include "bfmdemodsink.h" -class DownChannelizer; class SpectrumVis; class BFMDemodBaseband : public QObject @@ -85,7 +85,7 @@ public: private: SampleSinkFifo m_sampleFifo; - DownChannelizer *m_channelizer; + DownChannelizer m_channelizer; int m_channelSampleRate; BFMDemodSink m_sink; MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication