diff --git a/plugins/channelrx/demodnfm/nfmdemod.cpp b/plugins/channelrx/demodnfm/nfmdemod.cpp index 39c323b6d..c2498da13 100644 --- a/plugins/channelrx/demodnfm/nfmdemod.cpp +++ b/plugins/channelrx/demodnfm/nfmdemod.cpp @@ -53,21 +53,11 @@ const int NFMDemod::m_udpBlockSize = 512; NFMDemod::NFMDemod(DeviceAPI *devieAPI) : ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), m_deviceAPI(devieAPI), + m_running(false), m_basebandSampleRate(0) { qDebug("NFMDemod::NFMDemod"); setObjectName(m_channelId); - - m_thread = new QThread(this); - m_basebandSink = new NFMDemodBaseband(); - m_basebandSink->setFifoLabel(QString("%1 [%2:%3]") - .arg(m_channelId) - .arg(m_deviceAPI->getDeviceSetIndex()) - .arg(getIndexInDeviceSet()) - ); - m_basebandSink->setChannel(this); - m_basebandSink->moveToThread(m_thread); - applySettings(m_settings, true); m_deviceAPI->addChannelSink(this); @@ -86,6 +76,8 @@ NFMDemod::NFMDemod(DeviceAPI *devieAPI) : this, &NFMDemod::handleIndexInDeviceSetChanged ); + + start(); } NFMDemod::~NFMDemod() @@ -99,8 +91,8 @@ NFMDemod::~NFMDemod() delete m_networkManager; m_deviceAPI->removeChannelSinkAPI(this); m_deviceAPI->removeChannelSink(this); - delete m_basebandSink; - delete m_thread; + + stop(); } void NFMDemod::setDeviceAPI(DeviceAPI *deviceAPI) @@ -128,20 +120,55 @@ void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto void NFMDemod::start() { + if (m_running) { + return; + } + qDebug() << "NFMDemod::start"; + m_thread = new QThread(); + m_basebandSink = new NFMDemodBaseband(); + m_basebandSink->setFifoLabel(QString("%1 [%2:%3]") + .arg(m_channelId) + .arg(m_deviceAPI->getDeviceSetIndex()) + .arg(getIndexInDeviceSet()) + ); + 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(); + + NFMDemodBaseband::MsgConfigureNFMDemodBaseband *msg = NFMDemodBaseband::MsgConfigureNFMDemodBaseband::create(m_settings, true); + m_basebandSink->getInputMessageQueue()->push(msg); + + m_running = true; } void NFMDemod::stop() { + if (!m_running) { + return; + } + qDebug() << "NFMDemod::stop"; - m_thread->exit(); + m_running = false; + m_thread->quit(); m_thread->wait(); } @@ -158,12 +185,14 @@ bool NFMDemod::handleMessage(const Message& cmd) } else if (DSPSignalNotification::match(cmd)) { + qDebug() << "NFMDemod::handleMessage: DSPSignalNotification"; DSPSignalNotification& notif = (DSPSignalNotification&) cmd; m_basebandSampleRate = notif.getSampleRate(); - // Forward to the sink - DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy - qDebug() << "NFMDemod::handleMessage: DSPSignalNotification"; - m_basebandSink->getInputMessageQueue()->push(rep); + // Forward to the sink if any + if (m_running) { + m_basebandSink->getInputMessageQueue()->push(new DSPSignalNotification(notif)); + } + // Forward to GUI if any if (getMessageQueueToGUI()) { getMessageQueueToGUI()->push(new DSPSignalNotification(notif)); @@ -285,8 +314,11 @@ void NFMDemod::applySettings(const NFMDemodSettings& settings, bool force) reverseAPIKeys.append("streamIndex"); } - NFMDemodBaseband::MsgConfigureNFMDemodBaseband *msg = NFMDemodBaseband::MsgConfigureNFMDemodBaseband::create(settings, force); - m_basebandSink->getInputMessageQueue()->push(msg); + if (m_running) + { + NFMDemodBaseband::MsgConfigureNFMDemodBaseband *msg = NFMDemodBaseband::MsgConfigureNFMDemodBaseband::create(settings, force); + m_basebandSink->getInputMessageQueue()->push(msg); + } if (settings.m_useReverseAPI) { @@ -557,19 +589,23 @@ void NFMDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response response.getNfmDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg)); int nbCtcssToneFrequencies; - const Real *ctcssToneFrequencies = m_basebandSink->getCtcssToneSet(nbCtcssToneFrequencies); - response.getNfmDemodReport()->setCtcssTone( - m_settings.m_ctcssOn ? - m_settings.m_ctcssIndex < 0 ? - 0 - : m_settings.m_ctcssIndex < nbCtcssToneFrequencies ? - ctcssToneFrequencies[m_settings.m_ctcssIndex-1] - : 0 - : 0 - ); - response.getNfmDemodReport()->setSquelch(m_basebandSink->getSquelchOpen() ? 1 : 0); - response.getNfmDemodReport()->setAudioSampleRate(m_basebandSink->getAudioSampleRate()); - response.getNfmDemodReport()->setChannelSampleRate(m_basebandSink->getChannelSampleRate()); + + if (m_running) + { + const Real *ctcssToneFrequencies = m_basebandSink->getCtcssToneSet(nbCtcssToneFrequencies); + response.getNfmDemodReport()->setCtcssTone( + m_settings.m_ctcssOn ? + m_settings.m_ctcssIndex < 0 ? + 0 + : m_settings.m_ctcssIndex < nbCtcssToneFrequencies ? + ctcssToneFrequencies[m_settings.m_ctcssIndex-1] + : 0 + : 0 + ); + response.getNfmDemodReport()->setSquelch(m_basebandSink->getSquelchOpen() ? 1 : 0); + response.getNfmDemodReport()->setAudioSampleRate(m_basebandSink->getAudioSampleRate()); + response.getNfmDemodReport()->setChannelSampleRate(m_basebandSink->getChannelSampleRate()); + } } void NFMDemod::webapiReverseSendSettings(QList& channelSettingsKeys, const NFMDemodSettings& settings, bool force) @@ -725,7 +761,7 @@ void NFMDemod::networkManagerFinished(QNetworkReply *reply) void NFMDemod::handleIndexInDeviceSetChanged(int index) { - if (index < 0) { + if (!m_running || (index < 0)) { return; } diff --git a/plugins/channelrx/demodnfm/nfmdemod.h b/plugins/channelrx/demodnfm/nfmdemod.h index 4e311d12c..6889407f6 100644 --- a/plugins/channelrx/demodnfm/nfmdemod.h +++ b/plugins/channelrx/demodnfm/nfmdemod.h @@ -138,6 +138,7 @@ private: DeviceAPI* m_deviceAPI; QThread *m_thread; NFMDemodBaseband* m_basebandSink; + bool m_running; NFMDemodSettings m_settings; int m_basebandSampleRate; //!< stored from device message used when starting baseband sink diff --git a/plugins/channelrx/demodnfm/nfmdemodbaseband.cpp b/plugins/channelrx/demodnfm/nfmdemodbaseband.cpp index 35e0e2c5e..7d73b0e4c 100644 --- a/plugins/channelrx/demodnfm/nfmdemodbaseband.cpp +++ b/plugins/channelrx/demodnfm/nfmdemodbaseband.cpp @@ -19,17 +19,16 @@ #include "dsp/dspengine.h" #include "dsp/dspcommands.h" -#include "dsp/downchannelizer.h" #include "nfmdemodbaseband.h" MESSAGE_CLASS_DEFINITION(NFMDemodBaseband::MsgConfigureNFMDemodBaseband, Message) NFMDemodBaseband::NFMDemodBaseband() : + m_channelizer(&m_sink), m_mutex(QMutex::Recursive) { m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000)); - m_channelizer = new DownChannelizer(&m_sink); qDebug("NFMDemodBaseband::NFMDemodBaseband"); QObject::connect( @@ -44,13 +43,18 @@ NFMDemodBaseband::NFMDemodBaseband() : m_sink.applyAudioSampleRate(DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate()); m_channelSampleRate = 0; - connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); + QObject::connect( + &m_inputMessageQueue, + &MessageQueue::messageEnqueued, + this, + &NFMDemodBaseband::handleInputMessages, + Qt::QueuedConnection + ); } NFMDemodBaseband::~NFMDemodBaseband() { DSPEngine::instance()->getAudioDeviceManager()->removeAudioSink(m_sink.getAudioFifo()); - delete m_channelizer; } void NFMDemodBaseband::reset() @@ -85,12 +89,12 @@ void NFMDemodBaseband::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); @@ -127,13 +131,13 @@ bool NFMDemodBaseband::handleMessage(const Message& cmd) DSPSignalNotification& notif = (DSPSignalNotification&) cmd; qDebug() << "NFMDemodBaseband::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; @@ -148,13 +152,13 @@ void NFMDemodBaseband::applySettings(const NFMDemodSettings& settings, bool forc { 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(); } } @@ -169,8 +173,8 @@ void NFMDemodBaseband::applySettings(const NFMDemodSettings& settings, bool forc 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); } } @@ -182,12 +186,12 @@ void NFMDemodBaseband::applySettings(const NFMDemodSettings& settings, bool forc int NFMDemodBaseband::getChannelSampleRate() const { - return m_channelizer->getChannelSampleRate(); + return m_channelizer.getChannelSampleRate(); } void NFMDemodBaseband::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/demodnfm/nfmdemodbaseband.h b/plugins/channelrx/demodnfm/nfmdemodbaseband.h index 7eb046d2f..11d540fed 100644 --- a/plugins/channelrx/demodnfm/nfmdemodbaseband.h +++ b/plugins/channelrx/demodnfm/nfmdemodbaseband.h @@ -22,12 +22,12 @@ #include #include "dsp/samplesinkfifo.h" +#include "dsp/downchannelizer.h" #include "util/message.h" #include "util/messagequeue.h" #include "nfmdemodsink.h" -class DownChannelizer; class ChannelAPI; class NFMDemodBaseband : public QObject @@ -75,7 +75,7 @@ public: private: SampleSinkFifo m_sampleFifo; - DownChannelizer *m_channelizer; + DownChannelizer m_channelizer; int m_channelSampleRate; NFMDemodSink m_sink; MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication