mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-30 12:30:20 -04:00 
			
		
		
		
	BFM demod: updated threading model. Part of #1346
This commit is contained in:
		
							parent
							
								
									ab936710ea
								
							
						
					
					
						commit
						c9dad59438
					
				| @ -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; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -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
 | ||||
|  | ||||
| @ -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); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -22,12 +22,12 @@ | ||||
| #include <QRecursiveMutex> | ||||
| 
 | ||||
| #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
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user