From 01d28918a2a0f0b6ac35a3b067b20efc82c8edf1 Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 26 Jul 2022 00:45:43 +0200 Subject: [PATCH] SSB demod: applied new threading model. Part of #1346 --- plugins/channelrx/demodssb/ssbdemod.cpp | 88 +++++++++++++++---- plugins/channelrx/demodssb/ssbdemod.h | 2 + .../channelrx/demodssb/ssbdemodbaseband.cpp | 34 ++++--- plugins/channelrx/demodssb/ssbdemodbaseband.h | 4 +- 4 files changed, 89 insertions(+), 39 deletions(-) diff --git a/plugins/channelrx/demodssb/ssbdemod.cpp b/plugins/channelrx/demodssb/ssbdemod.cpp index 6712ba446..d043bbcf6 100644 --- a/plugins/channelrx/demodssb/ssbdemod.cpp +++ b/plugins/channelrx/demodssb/ssbdemod.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "SWGChannelSettings.h" #include "SWGWorkspaceInfo.h" @@ -51,17 +52,13 @@ const char* const SSBDemod::m_channelId = "SSBDemod"; SSBDemod::SSBDemod(DeviceAPI *deviceAPI) : ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), m_deviceAPI(deviceAPI), + m_mutex(QMutex::Recursive), + m_running(false), m_spectrumVis(SDR_RX_SCALEF), m_basebandSampleRate(0) { setObjectName(m_channelId); - m_thread = new QThread(this); - m_basebandSink = new SSBDemodBaseband(); - m_basebandSink->setSpectrumSink(&m_spectrumVis); - m_basebandSink->setChannel(this); - m_basebandSink->moveToThread(m_thread); - applySettings(m_settings, true); m_deviceAPI->addChannelSink(this); @@ -80,6 +77,8 @@ SSBDemod::SSBDemod(DeviceAPI *deviceAPI) : this, &SSBDemod::handleIndexInDeviceSetChanged ); + + start(); } SSBDemod::~SSBDemod() @@ -93,8 +92,8 @@ SSBDemod::~SSBDemod() delete m_networkManager; m_deviceAPI->removeChannelSinkAPI(this); m_deviceAPI->removeChannelSink(this); - delete m_basebandSink; - delete m_thread; + + stop(); } void SSBDemod::setDeviceAPI(DeviceAPI *deviceAPI) @@ -117,24 +116,67 @@ uint32_t SSBDemod::getNumberOfDeviceStreams() const void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) { (void) positiveOnly; - m_basebandSink->feed(begin, end); + + if (m_running) { + m_basebandSink->feed(begin, end); + } } void SSBDemod::start() { + QMutexLocker m_lock(&m_mutex); + + if (m_running) { + return; + } + qDebug() << "SSBDemod::start"; + m_thread = new QThread(); + m_basebandSink = new SSBDemodBaseband(); + m_basebandSink->setFifoLabel(QString("%1 [%2:%3]") + .arg(m_channelId) + .arg(m_deviceAPI->getDeviceSetIndex()) + .arg(getIndexInDeviceSet()) + ); + 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); } - m_basebandSink->reset(); m_thread->start(); + + SSBDemodBaseband::MsgConfigureSSBDemodBaseband *msg = SSBDemodBaseband::MsgConfigureSSBDemodBaseband::create(m_settings, true); + m_basebandSink->getInputMessageQueue()->push(msg); + + m_running = true; } void SSBDemod::stop() { + QMutexLocker m_lock(&m_mutex); + + if (!m_running) { + return; + } + qDebug() << "SSBDemod::stop"; + m_running = false; m_thread->exit(); m_thread->wait(); } @@ -152,12 +194,13 @@ bool SSBDemod::handleMessage(const Message& cmd) } else if (DSPSignalNotification::match(cmd)) { + qDebug() << "SSBDemod::handleMessage: DSPSignalNotification"; DSPSignalNotification& notif = (DSPSignalNotification&) cmd; m_basebandSampleRate = notif.getSampleRate(); // Forward to the sink - DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy - qDebug() << "SSBDemod::handleMessage: DSPSignalNotification"; - m_basebandSink->getInputMessageQueue()->push(rep); + if (m_running) { + m_basebandSink->getInputMessageQueue()->push(new DSPSignalNotification(notif)); + } // Forwatd to GUI if any if (getMessageQueueToGUI()) { getMessageQueueToGUI()->push(new DSPSignalNotification(notif)); @@ -297,8 +340,11 @@ void SSBDemod::applySettings(const SSBDemodSettings& settings, bool force) m_spectrumVis.getInputMessageQueue()->push(msg); } - SSBDemodBaseband::MsgConfigureSSBDemodBaseband *msg = SSBDemodBaseband::MsgConfigureSSBDemodBaseband::create(settings, force); - m_basebandSink->getInputMessageQueue()->push(msg); + if (m_running) + { + SSBDemodBaseband::MsgConfigureSSBDemodBaseband *msg = SSBDemodBaseband::MsgConfigureSSBDemodBaseband::create(settings, force); + m_basebandSink->getInputMessageQueue()->push(msg); + } if (settings.m_useReverseAPI) { @@ -608,9 +654,13 @@ void SSBDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples); response.getSsbDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg)); - response.getSsbDemodReport()->setSquelch(m_basebandSink->getAudioActive() ? 1 : 0); - response.getSsbDemodReport()->setAudioSampleRate(m_basebandSink->getAudioSampleRate()); - response.getSsbDemodReport()->setChannelSampleRate(m_basebandSink->getChannelSampleRate()); + + if (m_running) + { + response.getSsbDemodReport()->setSquelch(m_basebandSink->getAudioActive() ? 1 : 0); + response.getSsbDemodReport()->setAudioSampleRate(m_basebandSink->getAudioSampleRate()); + response.getSsbDemodReport()->setChannelSampleRate(m_basebandSink->getChannelSampleRate()); + } } void SSBDemod::webapiReverseSendSettings(QList& channelSettingsKeys, const SSBDemodSettings& settings, bool force) @@ -787,7 +837,7 @@ void SSBDemod::networkManagerFinished(QNetworkReply *reply) void SSBDemod::handleIndexInDeviceSetChanged(int index) { - if (index < 0) { + if (!m_running || (index < 0)) { return; } diff --git a/plugins/channelrx/demodssb/ssbdemod.h b/plugins/channelrx/demodssb/ssbdemod.h index 5d8489a3c..3bb7e4cf9 100644 --- a/plugins/channelrx/demodssb/ssbdemod.h +++ b/plugins/channelrx/demodssb/ssbdemod.h @@ -143,6 +143,8 @@ private: DeviceAPI *m_deviceAPI; QThread *m_thread; SSBDemodBaseband* m_basebandSink; + QMutex m_mutex; + bool m_running; SSBDemodSettings m_settings; SpectrumVis m_spectrumVis; int m_basebandSampleRate; //!< stored from device message used when starting baseband sink diff --git a/plugins/channelrx/demodssb/ssbdemodbaseband.cpp b/plugins/channelrx/demodssb/ssbdemodbaseband.cpp index 682b0f82e..6af3ae540 100644 --- a/plugins/channelrx/demodssb/ssbdemodbaseband.cpp +++ b/plugins/channelrx/demodssb/ssbdemodbaseband.cpp @@ -19,7 +19,6 @@ #include "dsp/dspengine.h" #include "dsp/dspcommands.h" -#include "dsp/downchannelizer.h" #include "dsp/spectrumvis.h" #include "ssbdemodbaseband.h" @@ -27,12 +26,12 @@ MESSAGE_CLASS_DEFINITION(SSBDemodBaseband::MsgConfigureSSBDemodBaseband, Message) SSBDemodBaseband::SSBDemodBaseband() : + m_channelizer(&m_sink), m_messageQueueToGUI(nullptr), m_spectrumVis(nullptr), m_mutex(QMutex::Recursive) { m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000)); - m_channelizer = new DownChannelizer(&m_sink); qDebug("SSBDemodBaseband::SSBDemodBaseband"); QObject::connect( @@ -54,7 +53,6 @@ SSBDemodBaseband::SSBDemodBaseband() : SSBDemodBaseband::~SSBDemodBaseband() { DSPEngine::instance()->getAudioDeviceManager()->removeAudioSink(m_sink.getAudioFifo()); - delete m_channelizer; } void SSBDemodBaseband::reset() @@ -90,12 +88,12 @@ void SSBDemodBaseband::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); @@ -132,13 +130,13 @@ bool SSBDemodBaseband::handleMessage(const Message& cmd) DSPSignalNotification& notif = (DSPSignalNotification&) cmd; qDebug() << "SSBDemodBaseband::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_audioSampleRate); // reapply when channel sample rate changes - m_channelSampleRate = m_channelizer->getChannelSampleRate(); + m_channelSampleRate = m_channelizer.getChannelSampleRate(); } return true; @@ -153,13 +151,13 @@ void SSBDemodBaseband::applySettings(const SSBDemodSettings& settings, bool forc { if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) { - m_channelizer->setChannelization(m_audioSampleRate, settings.m_inputFrequencyOffset); - m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset()); + m_channelizer.setChannelization(m_audioSampleRate, 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_audioSampleRate); // reapply when channel sample rate changes - m_channelSampleRate = m_channelizer->getChannelSampleRate(); + m_channelSampleRate = m_channelizer.getChannelSampleRate(); } } @@ -182,8 +180,8 @@ void SSBDemodBaseband::applySettings(const SSBDemodSettings& settings, bool forc if (m_audioSampleRate != audioSampleRate) { m_sink.applyAudioSampleRate(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_audioSampleRate = audioSampleRate; if (getMessageQueueToGUI()) @@ -207,12 +205,12 @@ void SSBDemodBaseband::applySettings(const SSBDemodSettings& settings, bool forc int SSBDemodBaseband::getChannelSampleRate() const { - return m_channelizer->getChannelSampleRate(); + return m_channelizer.getChannelSampleRate(); } void SSBDemodBaseband::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/demodssb/ssbdemodbaseband.h b/plugins/channelrx/demodssb/ssbdemodbaseband.h index e14e3e431..f39ab87bf 100644 --- a/plugins/channelrx/demodssb/ssbdemodbaseband.h +++ b/plugins/channelrx/demodssb/ssbdemodbaseband.h @@ -22,12 +22,12 @@ #include #include "dsp/samplesinkfifo.h" +#include "dsp/downchannelizer.h" #include "util/message.h" #include "util/messagequeue.h" #include "ssbdemodsink.h" -class DownChannelizer; class ChannelAPI; class SpectrumVis; @@ -77,7 +77,7 @@ public: private: SampleSinkFifo m_sampleFifo; - DownChannelizer *m_channelizer; + DownChannelizer m_channelizer; SSBDemodSink m_sink; MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication SSBDemodSettings m_settings;