mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 13:00:26 -04:00 
			
		
		
		
	Merge pull request #2104 from srcejon/freq_scanner
Don't call start() in demod constructors
This commit is contained in:
		
						commit
						7db387995e
					
				| @ -78,7 +78,6 @@ AMDemod::AMDemod(DeviceAPI *deviceAPI) : | |||||||
|         this, |         this, | ||||||
|         &AMDemod::handleIndexInDeviceSetChanged |         &AMDemod::handleIndexInDeviceSetChanged | ||||||
|     ); |     ); | ||||||
|     start(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| AMDemod::~AMDemod() | AMDemod::~AMDemod() | ||||||
|  | |||||||
| @ -53,17 +53,11 @@ const int BFMDemod::m_udpBlockSize = 512; | |||||||
| BFMDemod::BFMDemod(DeviceAPI *deviceAPI) : | BFMDemod::BFMDemod(DeviceAPI *deviceAPI) : | ||||||
|     ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), |     ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), | ||||||
|     m_deviceAPI(deviceAPI), |     m_deviceAPI(deviceAPI), | ||||||
|  |     m_running(false), | ||||||
|     m_spectrumVis(SDR_RX_SCALEF), |     m_spectrumVis(SDR_RX_SCALEF), | ||||||
|     m_basebandSampleRate(0) |     m_basebandSampleRate(0) | ||||||
| { | { | ||||||
| 	setObjectName(m_channelId); | 	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); | 	applySettings(m_settings, true); | ||||||
| 
 | 
 | ||||||
|     m_deviceAPI->addChannelSink(this); |     m_deviceAPI->addChannelSink(this); | ||||||
| @ -96,8 +90,7 @@ BFMDemod::~BFMDemod() | |||||||
| 
 | 
 | ||||||
|     m_deviceAPI->removeChannelSinkAPI(this); |     m_deviceAPI->removeChannelSinkAPI(this); | ||||||
|     m_deviceAPI->removeChannelSink(this); |     m_deviceAPI->removeChannelSink(this); | ||||||
|     delete m_basebandSink; |     stop(); | ||||||
|     delete m_thread; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BFMDemod::setDeviceAPI(DeviceAPI *deviceAPI) | void BFMDemod::setDeviceAPI(DeviceAPI *deviceAPI) | ||||||
| @ -125,25 +118,48 @@ void BFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto | |||||||
| 
 | 
 | ||||||
| void BFMDemod::start() | void BFMDemod::start() | ||||||
| { | { | ||||||
|     qDebug() << "BFMDemod::start"; |     if (m_running) { | ||||||
| 
 |         return; | ||||||
|     if (m_basebandSampleRate != 0) { |  | ||||||
|         m_basebandSink->setBasebandSampleRate(m_basebandSampleRate); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     qDebug() << "BFMDemod::start"; | ||||||
|  |     m_thread = new QThread(); | ||||||
|  |     m_basebandSink = new BFMDemodBaseband(); | ||||||
|  |     m_basebandSink->setSpectrumSink(&m_spectrumVis); | ||||||
|  |     m_basebandSink->setChannel(this); | ||||||
|  |     m_basebandSink->moveToThread(m_thread); | ||||||
|  |     m_basebandSink->setMessageQueueToGUI(getMessageQueueToGUI()); | ||||||
|  | 
 | ||||||
|  |     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->reset(); | ||||||
|  |     m_basebandSink->startWork(); | ||||||
|     m_thread->start(); |     m_thread->start(); | ||||||
| 
 | 
 | ||||||
|  |     DSPSignalNotification *dspMsg = new DSPSignalNotification(m_basebandSampleRate, 0); | ||||||
|  |     m_basebandSink->getInputMessageQueue()->push(dspMsg); | ||||||
|  | 
 | ||||||
|  |     BFMDemodBaseband::MsgConfigureBFMDemodBaseband *msg = BFMDemodBaseband::MsgConfigureBFMDemodBaseband::create(m_settings, true); | ||||||
|  |     m_basebandSink->getInputMessageQueue()->push(msg); | ||||||
|  | 
 | ||||||
|     SpectrumSettings spectrumSettings = m_spectrumVis.getSettings(); |     SpectrumSettings spectrumSettings = m_spectrumVis.getSettings(); | ||||||
|     spectrumSettings.m_ssb = true; |     spectrumSettings.m_ssb = true; | ||||||
|     SpectrumVis::MsgConfigureSpectrumVis *msg = SpectrumVis::MsgConfigureSpectrumVis::create(spectrumSettings, false); |     SpectrumVis::MsgConfigureSpectrumVis *visMsg = SpectrumVis::MsgConfigureSpectrumVis::create(spectrumSettings, false); | ||||||
|     m_spectrumVis.getInputMessageQueue()->push(msg); |     m_spectrumVis.getInputMessageQueue()->push(visMsg); | ||||||
|  | 
 | ||||||
|  |     m_running = true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BFMDemod::stop() | void BFMDemod::stop() | ||||||
| { | { | ||||||
|  |     if (!m_running) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     qDebug() << "BFMDemod::stop"; |     qDebug() << "BFMDemod::stop"; | ||||||
| 	m_thread->exit(); |     m_running = false; | ||||||
|  | 	m_thread->quit(); | ||||||
| 	m_thread->wait(); | 	m_thread->wait(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -163,9 +179,12 @@ bool BFMDemod::handleMessage(const Message& cmd) | |||||||
|         DSPSignalNotification& notif = (DSPSignalNotification&) cmd; |         DSPSignalNotification& notif = (DSPSignalNotification&) cmd; | ||||||
|         m_basebandSampleRate = notif.getSampleRate(); |         m_basebandSampleRate = notif.getSampleRate(); | ||||||
|         // Forward to the sink
 |         // Forward to the sink
 | ||||||
|         DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy
 |         if (m_running) | ||||||
|         qDebug() << "BFMDemod::handleMessage: DSPSignalNotification"; |         { | ||||||
|         m_basebandSink->getInputMessageQueue()->push(rep); |             DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy
 | ||||||
|  |             qDebug() << "BFMDemod::handleMessage: DSPSignalNotification"; | ||||||
|  |             m_basebandSink->getInputMessageQueue()->push(rep); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         if (getMessageQueueToGUI()) { |         if (getMessageQueueToGUI()) { | ||||||
|             getMessageQueueToGUI()->push(new DSPSignalNotification(notif)); |             getMessageQueueToGUI()->push(new DSPSignalNotification(notif)); | ||||||
| @ -257,8 +276,11 @@ void BFMDemod::applySettings(const BFMDemodSettings& settings, bool force) | |||||||
|         reverseAPIKeys.append("streamIndex"); |         reverseAPIKeys.append("streamIndex"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     BFMDemodBaseband::MsgConfigureBFMDemodBaseband *msg = BFMDemodBaseband::MsgConfigureBFMDemodBaseband::create(settings, force); |     if (m_running) | ||||||
|     m_basebandSink->getInputMessageQueue()->push(msg); |     { | ||||||
|  |         BFMDemodBaseband::MsgConfigureBFMDemodBaseband *msg = BFMDemodBaseband::MsgConfigureBFMDemodBaseband::create(settings, force); | ||||||
|  |         m_basebandSink->getInputMessageQueue()->push(msg); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (settings.m_useReverseAPI) |     if (settings.m_useReverseAPI) | ||||||
|     { |     { | ||||||
| @ -511,6 +533,10 @@ void BFMDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& resp | |||||||
| 
 | 
 | ||||||
| void BFMDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) | void BFMDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) | ||||||
| { | { | ||||||
|  |     if (!m_running) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     double magsqAvg, magsqPeak; |     double magsqAvg, magsqPeak; | ||||||
|     int nbMagsqSamples; |     int nbMagsqSamples; | ||||||
|     getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples); |     getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples); | ||||||
| @ -535,28 +561,31 @@ void BFMDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response | |||||||
| 
 | 
 | ||||||
| void BFMDemod::webapiFormatRDSReport(SWGSDRangel::SWGRDSReport *report) | void BFMDemod::webapiFormatRDSReport(SWGSDRangel::SWGRDSReport *report) | ||||||
| { | { | ||||||
|     report->setDemodStatus(round(getDemodQua())); |     if (getRDSParser()) | ||||||
|     report->setDecodStatus(round(getDecoderQua())); |  | ||||||
|     report->setRdsDemodAccumDb(CalcDb::dbPower(std::fabs(getDemodAcc()))); |  | ||||||
|     report->setRdsDemodFrequency(getDemodFclk()); |  | ||||||
|     report->setPid(new QString(str(boost::format("%04X") % getRDSParser().m_pi_program_identification).c_str())); |  | ||||||
|     report->setPiType(new QString(getRDSParser().pty_table[getRDSParser().m_pi_program_type].c_str())); |  | ||||||
|     report->setPiCoverage(new QString(getRDSParser().coverage_area_codes[getRDSParser().m_pi_area_coverage_index].c_str())); |  | ||||||
|     report->setProgServiceName(new QString(getRDSParser().m_g0_program_service_name)); |  | ||||||
|     report->setMusicSpeech(new QString((getRDSParser().m_g0_music_speech ? "Music" : "Speech"))); |  | ||||||
|     report->setMonoStereo(new QString((getRDSParser().m_g0_mono_stereo ? "Mono" : "Stereo"))); |  | ||||||
|     report->setRadioText(new QString(getRDSParser().m_g2_radiotext)); |  | ||||||
|     std::string time = str(boost::format("%4i-%02i-%02i %02i:%02i (%+.1fh)")\ |  | ||||||
|         % (1900 + getRDSParser().m_g4_year) % getRDSParser().m_g4_month % getRDSParser().m_g4_day % getRDSParser().m_g4_hours % getRDSParser().m_g4_minutes % getRDSParser().m_g4_local_time_offset); |  | ||||||
|     report->setTime(new QString(time.c_str())); |  | ||||||
|     report->setAltFrequencies(new QList<SWGSDRangel::SWGRDSReport_altFrequencies*>); |  | ||||||
| 
 |  | ||||||
|     for (std::set<double>::iterator it = getRDSParser().m_g0_alt_freq.begin(); it != getRDSParser().m_g0_alt_freq.end(); ++it) |  | ||||||
|     { |     { | ||||||
|         if (*it > 76.0) |         report->setDemodStatus(round(getDemodQua())); | ||||||
|  |         report->setDecodStatus(round(getDecoderQua())); | ||||||
|  |         report->setRdsDemodAccumDb(CalcDb::dbPower(std::fabs(getDemodAcc()))); | ||||||
|  |         report->setRdsDemodFrequency(getDemodFclk()); | ||||||
|  |         report->setPid(new QString(str(boost::format("%04X") % getRDSParser()->m_pi_program_identification).c_str())); | ||||||
|  |         report->setPiType(new QString(getRDSParser()->pty_table[getRDSParser()->m_pi_program_type].c_str())); | ||||||
|  |         report->setPiCoverage(new QString(getRDSParser()->coverage_area_codes[getRDSParser()->m_pi_area_coverage_index].c_str())); | ||||||
|  |         report->setProgServiceName(new QString(getRDSParser()->m_g0_program_service_name)); | ||||||
|  |         report->setMusicSpeech(new QString((getRDSParser()->m_g0_music_speech ? "Music" : "Speech"))); | ||||||
|  |         report->setMonoStereo(new QString((getRDSParser()->m_g0_mono_stereo ? "Mono" : "Stereo"))); | ||||||
|  |         report->setRadioText(new QString(getRDSParser()->m_g2_radiotext)); | ||||||
|  |         std::string time = str(boost::format("%4i-%02i-%02i %02i:%02i (%+.1fh)")\ | ||||||
|  |             % (1900 + getRDSParser()->m_g4_year) % getRDSParser()->m_g4_month % getRDSParser()->m_g4_day % getRDSParser()->m_g4_hours % getRDSParser()->m_g4_minutes % getRDSParser()->m_g4_local_time_offset); | ||||||
|  |         report->setTime(new QString(time.c_str())); | ||||||
|  |         report->setAltFrequencies(new QList<SWGSDRangel::SWGRDSReport_altFrequencies*>); | ||||||
|  | 
 | ||||||
|  |         for (std::set<double>::iterator it = getRDSParser()->m_g0_alt_freq.begin(); it != getRDSParser()->m_g0_alt_freq.end(); ++it) | ||||||
|         { |         { | ||||||
|             report->getAltFrequencies()->append(new SWGSDRangel::SWGRDSReport_altFrequencies); |             if (*it > 76.0) | ||||||
|             report->getAltFrequencies()->back()->setFrequency(*it); |             { | ||||||
|  |                 report->getAltFrequencies()->append(new SWGSDRangel::SWGRDSReport_altFrequencies); | ||||||
|  |                 report->getAltFrequencies()->back()->setFrequency(*it); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -712,7 +741,7 @@ void BFMDemod::networkManagerFinished(QNetworkReply *reply) | |||||||
| 
 | 
 | ||||||
| void BFMDemod::handleIndexInDeviceSetChanged(int index) | void BFMDemod::handleIndexInDeviceSetChanged(int index) | ||||||
| { | { | ||||||
|     if (index < 0) { |     if (!m_running || (index < 0)) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -76,7 +76,6 @@ public: | |||||||
|     virtual void setDeviceAPI(DeviceAPI *deviceAPI); |     virtual void setDeviceAPI(DeviceAPI *deviceAPI); | ||||||
|     virtual DeviceAPI *getDeviceAPI() { return m_deviceAPI; } |     virtual DeviceAPI *getDeviceAPI() { return m_deviceAPI; } | ||||||
|     SpectrumVis *getSpectrumVis() { return &m_spectrumVis; } |     SpectrumVis *getSpectrumVis() { return &m_spectrumVis; } | ||||||
|     void setBasebandMessageQueueToGUI(MessageQueue *messageQueue) { m_basebandSink->setMessageQueueToGUI(messageQueue); } |  | ||||||
| 
 | 
 | ||||||
|     using BasebandSampleSink::feed; |     using BasebandSampleSink::feed; | ||||||
|     virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po); |     virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po); | ||||||
| @ -105,21 +104,27 @@ public: | |||||||
|         return m_settings.m_inputFrequencyOffset; |         return m_settings.m_inputFrequencyOffset; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	double getMagSq() const { return m_basebandSink->getMagSq(); } | 	double getMagSq() const { return m_running ? m_basebandSink->getMagSq() : 0.0; } | ||||||
| 
 | 
 | ||||||
| 	bool getPilotLock() const { return m_basebandSink->getPilotLock(); } | 	bool getPilotLock() const { return m_running ? m_basebandSink->getPilotLock() : false; } | ||||||
| 	Real getPilotLevel() const { return m_basebandSink->getPilotLevel(); } | 	Real getPilotLevel() const { return m_running ? m_basebandSink->getPilotLevel() : 0.0f; } | ||||||
| 
 | 
 | ||||||
| 	Real getDecoderQua() const { return m_basebandSink->getDecoderQua(); } | 	Real getDecoderQua() const { return m_running ? m_basebandSink->getDecoderQua() : 0.0f; } | ||||||
| 	bool getDecoderSynced() const { return m_basebandSink->getDecoderSynced(); } | 	bool getDecoderSynced() const { return m_running ? m_basebandSink->getDecoderSynced() : false; } | ||||||
| 	Real getDemodAcc() const { return m_basebandSink->getDemodAcc(); } | 	Real getDemodAcc() const { return m_running ? m_basebandSink->getDemodAcc() : 0.0f; } | ||||||
| 	Real getDemodQua() const { return m_basebandSink->getDemodQua(); } | 	Real getDemodQua() const { return m_running ? m_basebandSink->getDemodQua() : 0.0f; } | ||||||
| 	Real getDemodFclk() const { return m_basebandSink->getDemodFclk(); } | 	Real getDemodFclk() const { return m_running ? m_basebandSink->getDemodFclk() : 0.0f; } | ||||||
|     int getAudioSampleRate() const { return m_basebandSink->getAudioSampleRate(); } |     int getAudioSampleRate() const { return m_running ? m_basebandSink->getAudioSampleRate() : 0; } | ||||||
| 
 | 
 | ||||||
|     void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_basebandSink->getMagSqLevels(avg, peak, nbSamples); } |     void getMagSqLevels(double& avg, double& peak, int& nbSamples) { | ||||||
|  |         if (m_running) { | ||||||
|  |             m_basebandSink->getMagSqLevels(avg, peak, nbSamples); | ||||||
|  |         } else { | ||||||
|  |             avg = 0.0; peak = 0.0; nbSamples = 1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     RDSParser& getRDSParser() { return m_basebandSink->getRDSParser(); } |     RDSParser *getRDSParser() { return m_running ? &m_basebandSink->getRDSParser() : nullptr; } | ||||||
| 
 | 
 | ||||||
|     virtual int webapiSettingsGet( |     virtual int webapiSettingsGet( | ||||||
|             SWGSDRangel::SWGChannelSettings& response, |             SWGSDRangel::SWGChannelSettings& response, | ||||||
| @ -157,6 +162,7 @@ private: | |||||||
| 	DeviceAPI *m_deviceAPI; | 	DeviceAPI *m_deviceAPI; | ||||||
|     QThread *m_thread; |     QThread *m_thread; | ||||||
|     BFMDemodBaseband* m_basebandSink; |     BFMDemodBaseband* m_basebandSink; | ||||||
|  |     bool m_running; | ||||||
| 	BFMDemodSettings m_settings; | 	BFMDemodSettings m_settings; | ||||||
|     SpectrumVis m_spectrumVis; |     SpectrumVis m_spectrumVis; | ||||||
|     int m_basebandSampleRate; //!< stored from device message used when starting baseband sink
 |     int m_basebandSampleRate; //!< stored from device message used when starting baseband sink
 | ||||||
|  | |||||||
| @ -30,26 +30,19 @@ | |||||||
| MESSAGE_CLASS_DEFINITION(BFMDemodBaseband::MsgConfigureBFMDemodBaseband, Message) | MESSAGE_CLASS_DEFINITION(BFMDemodBaseband::MsgConfigureBFMDemodBaseband, Message) | ||||||
| 
 | 
 | ||||||
| BFMDemodBaseband::BFMDemodBaseband() : | BFMDemodBaseband::BFMDemodBaseband() : | ||||||
|  |     m_running(false), | ||||||
|     m_messageQueueToGUI(nullptr), |     m_messageQueueToGUI(nullptr), | ||||||
|     m_spectrumVis(nullptr) |     m_spectrumVis(nullptr) | ||||||
|  | 
 | ||||||
| { | { | ||||||
|     m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000)); |     m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000)); | ||||||
|     m_channelizer = new DownChannelizer(&m_sink); |     m_channelizer = new DownChannelizer(&m_sink); | ||||||
| 
 | 
 | ||||||
|     qDebug("BFMDemodBaseband::BFMDemodBaseband"); |     qDebug("BFMDemodBaseband::BFMDemodBaseband"); | ||||||
|     QObject::connect( |  | ||||||
|         &m_sampleFifo, |  | ||||||
|         &SampleSinkFifo::dataReady, |  | ||||||
|         this, |  | ||||||
|         &BFMDemodBaseband::handleData, |  | ||||||
|         Qt::QueuedConnection |  | ||||||
|     ); |  | ||||||
| 
 | 
 | ||||||
|     DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue()); |     DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue()); | ||||||
|     m_sink.applyAudioSampleRate(DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate()); |     m_sink.applyAudioSampleRate(DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate()); | ||||||
|     m_channelSampleRate = 0; |     m_channelSampleRate = 0; | ||||||
| 
 |  | ||||||
|     connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BFMDemodBaseband::~BFMDemodBaseband() | BFMDemodBaseband::~BFMDemodBaseband() | ||||||
| @ -61,10 +54,38 @@ BFMDemodBaseband::~BFMDemodBaseband() | |||||||
| void BFMDemodBaseband::reset() | void BFMDemodBaseband::reset() | ||||||
| { | { | ||||||
|     QMutexLocker mutexLocker(&m_mutex); |     QMutexLocker mutexLocker(&m_mutex); | ||||||
|  |     m_inputMessageQueue.clear(); | ||||||
|     m_sampleFifo.reset(); |     m_sampleFifo.reset(); | ||||||
|     m_channelSampleRate = 0; |     m_channelSampleRate = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void BFMDemodBaseband::startWork() | ||||||
|  | { | ||||||
|  |     QMutexLocker mutexLocker(&m_mutex); | ||||||
|  |     QObject::connect( | ||||||
|  |         &m_sampleFifo, | ||||||
|  |         &SampleSinkFifo::dataReady, | ||||||
|  |         this, | ||||||
|  |         &BFMDemodBaseband::handleData, | ||||||
|  |         Qt::QueuedConnection | ||||||
|  |     ); | ||||||
|  |     connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); | ||||||
|  |     m_running = true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void BFMDemodBaseband::stopWork() | ||||||
|  | { | ||||||
|  |     QMutexLocker mutexLocker(&m_mutex); | ||||||
|  |     disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); | ||||||
|  |     QObject::disconnect( | ||||||
|  |         &m_sampleFifo, | ||||||
|  |         &SampleSinkFifo::dataReady, | ||||||
|  |         this, | ||||||
|  |         &BFMDemodBaseband::handleData | ||||||
|  |     ); | ||||||
|  |     m_running = false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void BFMDemodBaseband::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end) | void BFMDemodBaseband::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end) | ||||||
| { | { | ||||||
|     m_sampleFifo.write(begin, end); |     m_sampleFifo.write(begin, end); | ||||||
|  | |||||||
| @ -62,12 +62,15 @@ public: | |||||||
|     BFMDemodBaseband(); |     BFMDemodBaseband(); | ||||||
|     ~BFMDemodBaseband(); |     ~BFMDemodBaseband(); | ||||||
|     void reset(); |     void reset(); | ||||||
|  |     void startWork(); | ||||||
|  |     void stopWork(); | ||||||
|     void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end); |     void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end); | ||||||
|     MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
 |     MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
 | ||||||
|     int getChannelSampleRate() const; |     int getChannelSampleRate() const; | ||||||
|     void setBasebandSampleRate(int sampleRate); |     void setBasebandSampleRate(int sampleRate); | ||||||
|     void setSpectrumSink(SpectrumVis* spectrumSink) { m_spectrumVis = spectrumSink; m_sink.setSpectrumSink((BasebandSampleSink*) spectrumSink); } |     void setSpectrumSink(SpectrumVis* spectrumSink) { m_spectrumVis = spectrumSink; m_sink.setSpectrumSink((BasebandSampleSink*) spectrumSink); } | ||||||
|     void setChannel(ChannelAPI *channel); |     void setChannel(ChannelAPI *channel); | ||||||
|  |     bool isRunning() const { return m_running; } | ||||||
|     void setMessageQueueToGUI(MessageQueue *messageQueue) { m_messageQueueToGUI = messageQueue; } |     void setMessageQueueToGUI(MessageQueue *messageQueue) { m_messageQueueToGUI = messageQueue; } | ||||||
| 
 | 
 | ||||||
|     int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } |     int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } | ||||||
| @ -92,6 +95,7 @@ private: | |||||||
|     BFMDemodSink m_sink; |     BFMDemodSink m_sink; | ||||||
| 	MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication
 | 	MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication
 | ||||||
|     BFMDemodSettings m_settings; |     BFMDemodSettings m_settings; | ||||||
|  |     bool m_running; | ||||||
|     QRecursiveMutex m_mutex; |     QRecursiveMutex m_mutex; | ||||||
|     MessageQueue *m_messageQueueToGUI; |     MessageQueue *m_messageQueueToGUI; | ||||||
|     SpectrumVis *m_spectrumVis; |     SpectrumVis *m_spectrumVis; | ||||||
|  | |||||||
| @ -227,7 +227,9 @@ void BFMDemodGUI::on_clearData_clicked(bool checked) | |||||||
|     (void) checked; |     (void) checked; | ||||||
| 	if (ui->rds->isChecked()) | 	if (ui->rds->isChecked()) | ||||||
| 	{ | 	{ | ||||||
| 		m_bfmDemod->getRDSParser().clearAllFields(); | 		if (m_bfmDemod->getRDSParser()) { | ||||||
|  | 			m_bfmDemod->getRDSParser()->clearAllFields(); | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		ui->g00ProgServiceName->clear(); | 		ui->g00ProgServiceName->clear(); | ||||||
| 		ui->go2Text->clear(); | 		ui->go2Text->clear(); | ||||||
| @ -246,14 +248,18 @@ void BFMDemodGUI::on_clearData_clicked(bool checked) | |||||||
| 
 | 
 | ||||||
| void BFMDemodGUI::on_g14ProgServiceNames_currentIndexChanged(int _index) | void BFMDemodGUI::on_g14ProgServiceNames_currentIndexChanged(int _index) | ||||||
| { | { | ||||||
|  | 	if (!m_bfmDemod->getRDSParser()) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|     uint32_t index = _index & 0x7FFFFFF; |     uint32_t index = _index & 0x7FFFFFF; | ||||||
| 
 | 
 | ||||||
| 	if (index < m_g14ComboIndex.size()) | 	if (index < m_g14ComboIndex.size()) | ||||||
| 	{ | 	{ | ||||||
| 		unsigned int piKey = m_g14ComboIndex[index]; | 		unsigned int piKey = m_g14ComboIndex[index]; | ||||||
| 		RDSParser::freqs_map_t::const_iterator mIt = m_bfmDemod->getRDSParser().m_g14_mapped_freqs.find(piKey); | 		RDSParser::freqs_map_t::const_iterator mIt = m_bfmDemod->getRDSParser()->m_g14_mapped_freqs.find(piKey); | ||||||
| 
 | 
 | ||||||
| 		if (mIt != m_bfmDemod->getRDSParser().m_g14_mapped_freqs.end()) | 		if (mIt != m_bfmDemod->getRDSParser()->m_g14_mapped_freqs.end()) | ||||||
| 		{ | 		{ | ||||||
| 			ui->g14MappedFrequencies->clear(); | 			ui->g14MappedFrequencies->clear(); | ||||||
| 			RDSParser::freqs_set_t::iterator sIt = (mIt->second).begin(); | 			RDSParser::freqs_set_t::iterator sIt = (mIt->second).begin(); | ||||||
| @ -269,9 +275,9 @@ void BFMDemodGUI::on_g14ProgServiceNames_currentIndexChanged(int _index) | |||||||
| 			ui->g14MappedFrequencies->setEnabled(ui->g14MappedFrequencies->count() > 0); | 			ui->g14MappedFrequencies->setEnabled(ui->g14MappedFrequencies->count() > 0); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		mIt = m_bfmDemod->getRDSParser().m_g14_alt_freqs.find(piKey); | 		mIt = m_bfmDemod->getRDSParser()->m_g14_alt_freqs.find(piKey); | ||||||
| 
 | 
 | ||||||
| 		if (mIt != m_bfmDemod->getRDSParser().m_g14_alt_freqs.end()) | 		if (mIt != m_bfmDemod->getRDSParser()->m_g14_alt_freqs.end()) | ||||||
| 		{ | 		{ | ||||||
| 			ui->g14AltFrequencies->clear(); | 			ui->g14AltFrequencies->clear(); | ||||||
| 			RDSParser::freqs_set_t::iterator sIt = (mIt->second).begin(); | 			RDSParser::freqs_set_t::iterator sIt = (mIt->second).begin(); | ||||||
| @ -407,7 +413,6 @@ BFMDemodGUI::BFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban | |||||||
|     m_spectrumVis = m_bfmDemod->getSpectrumVis(); |     m_spectrumVis = m_bfmDemod->getSpectrumVis(); | ||||||
| 	m_spectrumVis->setGLSpectrum(ui->glSpectrum); | 	m_spectrumVis->setGLSpectrum(ui->glSpectrum); | ||||||
| 	m_bfmDemod->setMessageQueueToGUI(getInputMessageQueue()); | 	m_bfmDemod->setMessageQueueToGUI(getInputMessageQueue()); | ||||||
|     m_bfmDemod->setBasebandMessageQueueToGUI(getInputMessageQueue()); |  | ||||||
| 
 | 
 | ||||||
| 	ui->spectrumGUI->setBuddies(m_spectrumVis, ui->glSpectrum); | 	ui->spectrumGUI->setBuddies(m_spectrumVis, ui->glSpectrum); | ||||||
| 
 | 
 | ||||||
| @ -597,33 +602,41 @@ void BFMDemodGUI::tick() | |||||||
| 
 | 
 | ||||||
| void BFMDemodGUI::rdsUpdateFixedFields() | void BFMDemodGUI::rdsUpdateFixedFields() | ||||||
| { | { | ||||||
| 	ui->g00Label->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[0].c_str()); | 	if (!m_bfmDemod->getRDSParser()) { | ||||||
| 	ui->g01Label->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[1].c_str()); | 		return; | ||||||
| 	ui->g02Label->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[2].c_str()); | 	} | ||||||
| 	ui->g03Label->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[3].c_str()); |  | ||||||
| 	ui->g04Label->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[4].c_str()); |  | ||||||
| 	//ui->g05Label->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[5].c_str());
 |  | ||||||
| 	//ui->g06Label->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[6].c_str());
 |  | ||||||
| 	//ui->g07Label->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[7].c_str());
 |  | ||||||
| 	ui->g08Label->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[8].c_str()); |  | ||||||
| 	ui->g09Label->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[9].c_str()); |  | ||||||
| 	ui->g14Label->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[14].c_str()); |  | ||||||
| 
 | 
 | ||||||
| 	ui->g00CountLabel->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[0].c_str()); | 	ui->g00Label->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[0].c_str()); | ||||||
| 	ui->g01CountLabel->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[1].c_str()); | 	ui->g01Label->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[1].c_str()); | ||||||
| 	ui->g02CountLabel->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[2].c_str()); | 	ui->g02Label->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[2].c_str()); | ||||||
| 	ui->g03CountLabel->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[3].c_str()); | 	ui->g03Label->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[3].c_str()); | ||||||
| 	ui->g04CountLabel->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[4].c_str()); | 	ui->g04Label->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[4].c_str()); | ||||||
| 	ui->g05CountLabel->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[5].c_str()); | 	//ui->g05Label->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[5].c_str());
 | ||||||
| 	ui->g06CountLabel->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[6].c_str()); | 	//ui->g06Label->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[6].c_str());
 | ||||||
| 	ui->g07CountLabel->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[7].c_str()); | 	//ui->g07Label->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[7].c_str());
 | ||||||
| 	ui->g08CountLabel->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[8].c_str()); | 	ui->g08Label->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[8].c_str()); | ||||||
| 	ui->g09CountLabel->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[9].c_str()); | 	ui->g09Label->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[9].c_str()); | ||||||
| 	ui->g14CountLabel->setText(m_bfmDemod->getRDSParser().rds_group_acronym_tags[14].c_str()); | 	ui->g14Label->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[14].c_str()); | ||||||
|  | 
 | ||||||
|  | 	ui->g00CountLabel->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[0].c_str()); | ||||||
|  | 	ui->g01CountLabel->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[1].c_str()); | ||||||
|  | 	ui->g02CountLabel->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[2].c_str()); | ||||||
|  | 	ui->g03CountLabel->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[3].c_str()); | ||||||
|  | 	ui->g04CountLabel->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[4].c_str()); | ||||||
|  | 	ui->g05CountLabel->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[5].c_str()); | ||||||
|  | 	ui->g06CountLabel->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[6].c_str()); | ||||||
|  | 	ui->g07CountLabel->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[7].c_str()); | ||||||
|  | 	ui->g08CountLabel->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[8].c_str()); | ||||||
|  | 	ui->g09CountLabel->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[9].c_str()); | ||||||
|  | 	ui->g14CountLabel->setText(m_bfmDemod->getRDSParser()->rds_group_acronym_tags[14].c_str()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BFMDemodGUI::rdsUpdate(bool force) | void BFMDemodGUI::rdsUpdate(bool force) | ||||||
| { | { | ||||||
|  | 	if (!m_bfmDemod->getRDSParser()) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	// Quality metrics
 | 	// Quality metrics
 | ||||||
| 	ui->demodQText->setText(QString("%1 %").arg(m_bfmDemod->getDemodQua(), 0, 'f', 0)); | 	ui->demodQText->setText(QString("%1 %").arg(m_bfmDemod->getDemodQua(), 0, 'f', 0)); | ||||||
| 	ui->decoderQText->setText(QString("%1 %").arg(m_bfmDemod->getDecoderQua(), 0, 'f', 0)); | 	ui->decoderQText->setText(QString("%1 %").arg(m_bfmDemod->getDecoderQua(), 0, 'f', 0)); | ||||||
| @ -638,21 +651,21 @@ void BFMDemodGUI::rdsUpdate(bool force) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// PI group
 | 	// PI group
 | ||||||
| 	if (m_bfmDemod->getRDSParser().m_pi_updated || force) | 	if (m_bfmDemod->getRDSParser()->m_pi_updated || force) | ||||||
| 	{ | 	{ | ||||||
| 		ui->piLabel->setStyleSheet("QLabel { background-color : green; }"); | 		ui->piLabel->setStyleSheet("QLabel { background-color : green; }"); | ||||||
| 		ui->piCountText->setNum((int) m_bfmDemod->getRDSParser().m_pi_count); | 		ui->piCountText->setNum((int) m_bfmDemod->getRDSParser()->m_pi_count); | ||||||
| 		QString pistring(str(boost::format("%04X") % m_bfmDemod->getRDSParser().m_pi_program_identification).c_str()); | 		QString pistring(str(boost::format("%04X") % m_bfmDemod->getRDSParser()->m_pi_program_identification).c_str()); | ||||||
| 		ui->piText->setText(pistring); | 		ui->piText->setText(pistring); | ||||||
| 
 | 
 | ||||||
| 		if (m_bfmDemod->getRDSParser().m_pi_traffic_program) { | 		if (m_bfmDemod->getRDSParser()->m_pi_traffic_program) { | ||||||
| 			ui->piTPIndicator->setStyleSheet("QLabel { background-color : green; }"); | 			ui->piTPIndicator->setStyleSheet("QLabel { background-color : green; }"); | ||||||
| 		} else { | 		} else { | ||||||
| 			ui->piTPIndicator->setStyleSheet("QLabel { background:rgb(79,79,79); }"); | 			ui->piTPIndicator->setStyleSheet("QLabel { background:rgb(79,79,79); }"); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		ui->piType->setText(QString(m_bfmDemod->getRDSParser().pty_table[m_bfmDemod->getRDSParser().m_pi_program_type].c_str())); | 		ui->piType->setText(QString(m_bfmDemod->getRDSParser()->pty_table[m_bfmDemod->getRDSParser()->m_pi_program_type].c_str())); | ||||||
| 		ui->piCoverage->setText(QString(m_bfmDemod->getRDSParser().coverage_area_codes[m_bfmDemod->getRDSParser().m_pi_area_coverage_index].c_str())); | 		ui->piCoverage->setText(QString(m_bfmDemod->getRDSParser()->coverage_area_codes[m_bfmDemod->getRDSParser()->m_pi_area_coverage_index].c_str())); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @ -660,29 +673,29 @@ void BFMDemodGUI::rdsUpdate(bool force) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// G0 group
 | 	// G0 group
 | ||||||
| 	if (m_bfmDemod->getRDSParser().m_g0_updated || force) | 	if (m_bfmDemod->getRDSParser()->m_g0_updated || force) | ||||||
| 	{ | 	{ | ||||||
| 		ui->g00Label->setStyleSheet("QLabel { background-color : green; }"); | 		ui->g00Label->setStyleSheet("QLabel { background-color : green; }"); | ||||||
| 		ui->g00CountText->setNum((int) m_bfmDemod->getRDSParser().m_g0_count); | 		ui->g00CountText->setNum((int) m_bfmDemod->getRDSParser()->m_g0_count); | ||||||
| 
 | 
 | ||||||
| 		if (m_bfmDemod->getRDSParser().m_g0_psn_bitmap == 0b1111) { | 		if (m_bfmDemod->getRDSParser()->m_g0_psn_bitmap == 0b1111) { | ||||||
| 			ui->g00ProgServiceName->setText(QString(m_bfmDemod->getRDSParser().m_g0_program_service_name)); | 			ui->g00ProgServiceName->setText(QString(m_bfmDemod->getRDSParser()->m_g0_program_service_name)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (m_bfmDemod->getRDSParser().m_g0_traffic_announcement) { | 		if (m_bfmDemod->getRDSParser()->m_g0_traffic_announcement) { | ||||||
| 			ui->g00TrafficAnnouncement->setStyleSheet("QLabel { background-color : green; }"); | 			ui->g00TrafficAnnouncement->setStyleSheet("QLabel { background-color : green; }"); | ||||||
| 		} else { | 		} else { | ||||||
| 			ui->g00TrafficAnnouncement->setStyleSheet("QLabel { background:rgb(79,79,79); }"); | 			ui->g00TrafficAnnouncement->setStyleSheet("QLabel { background:rgb(79,79,79); }"); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		ui->g00MusicSpeech->setText(QString((m_bfmDemod->getRDSParser().m_g0_music_speech ? "Music" : "Speech"))); | 		ui->g00MusicSpeech->setText(QString((m_bfmDemod->getRDSParser()->m_g0_music_speech ? "Music" : "Speech"))); | ||||||
| 		ui->g00MonoStereo->setText(QString((m_bfmDemod->getRDSParser().m_g0_mono_stereo ? "Mono" : "Stereo"))); | 		ui->g00MonoStereo->setText(QString((m_bfmDemod->getRDSParser()->m_g0_mono_stereo ? "Mono" : "Stereo"))); | ||||||
| 
 | 
 | ||||||
| 		if (m_bfmDemod->getRDSParser().m_g0_af_updated) | 		if (m_bfmDemod->getRDSParser()->m_g0_af_updated) | ||||||
| 		{ | 		{ | ||||||
| 			ui->g00AltFrequenciesBox->clear(); | 			ui->g00AltFrequenciesBox->clear(); | ||||||
| 
 | 
 | ||||||
| 			for (std::set<double>::iterator it = m_bfmDemod->getRDSParser().m_g0_alt_freq.begin(); it != m_bfmDemod->getRDSParser().m_g0_alt_freq.end(); ++it) | 			for (std::set<double>::iterator it = m_bfmDemod->getRDSParser()->m_g0_alt_freq.begin(); it != m_bfmDemod->getRDSParser()->m_g0_alt_freq.end(); ++it) | ||||||
| 			{ | 			{ | ||||||
| 				if (*it > 76.0) | 				if (*it > 76.0) | ||||||
| 				{ | 				{ | ||||||
| @ -701,20 +714,20 @@ void BFMDemodGUI::rdsUpdate(bool force) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// G1 group
 | 	// G1 group
 | ||||||
| 	if (m_bfmDemod->getRDSParser().m_g1_updated || force) | 	if (m_bfmDemod->getRDSParser()->m_g1_updated || force) | ||||||
| 	{ | 	{ | ||||||
| 		ui->g01Label->setStyleSheet("QLabel { background-color : green; }"); | 		ui->g01Label->setStyleSheet("QLabel { background-color : green; }"); | ||||||
| 		ui->g01CountText->setNum((int) m_bfmDemod->getRDSParser().m_g1_count); | 		ui->g01CountText->setNum((int) m_bfmDemod->getRDSParser()->m_g1_count); | ||||||
| 
 | 
 | ||||||
| 		if ((m_bfmDemod->getRDSParser().m_g1_country_page_index >= 0) && (m_bfmDemod->getRDSParser().m_g1_country_index >= 0)) { | 		if ((m_bfmDemod->getRDSParser()->m_g1_country_page_index >= 0) && (m_bfmDemod->getRDSParser()->m_g1_country_index >= 0)) { | ||||||
| 			ui->g01CountryCode->setText(QString((m_bfmDemod->getRDSParser().pi_country_codes[m_bfmDemod->getRDSParser().m_g1_country_page_index][m_bfmDemod->getRDSParser().m_g1_country_index]).c_str())); | 			ui->g01CountryCode->setText(QString((m_bfmDemod->getRDSParser()->pi_country_codes[m_bfmDemod->getRDSParser()->m_g1_country_page_index][m_bfmDemod->getRDSParser()->m_g1_country_index]).c_str())); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (m_bfmDemod->getRDSParser().m_g1_language_index >= 0) { | 		if (m_bfmDemod->getRDSParser()->m_g1_language_index >= 0) { | ||||||
| 			ui->g01Language->setText(QString(m_bfmDemod->getRDSParser().language_codes[m_bfmDemod->getRDSParser().m_g1_language_index].c_str())); | 			ui->g01Language->setText(QString(m_bfmDemod->getRDSParser()->language_codes[m_bfmDemod->getRDSParser()->m_g1_language_index].c_str())); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		ui->g01DHM->setText(QString(str(boost::format("%id:%i:%i") % m_bfmDemod->getRDSParser().m_g1_pin_day % m_bfmDemod->getRDSParser().m_g1_pin_hour % m_bfmDemod->getRDSParser().m_g1_pin_minute).c_str())); | 		ui->g01DHM->setText(QString(str(boost::format("%id:%i:%i") % m_bfmDemod->getRDSParser()->m_g1_pin_day % m_bfmDemod->getRDSParser()->m_g1_pin_hour % m_bfmDemod->getRDSParser()->m_g1_pin_minute).c_str())); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @ -722,11 +735,11 @@ void BFMDemodGUI::rdsUpdate(bool force) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// G2 group
 | 	// G2 group
 | ||||||
| 	if (m_bfmDemod->getRDSParser().m_g2_updated || force) | 	if (m_bfmDemod->getRDSParser()->m_g2_updated || force) | ||||||
| 	{ | 	{ | ||||||
| 		ui->g02Label->setStyleSheet("QLabel { background-color : green; }"); | 		ui->g02Label->setStyleSheet("QLabel { background-color : green; }"); | ||||||
| 		ui->g02CountText->setNum((int) m_bfmDemod->getRDSParser().m_g2_count); | 		ui->g02CountText->setNum((int) m_bfmDemod->getRDSParser()->m_g2_count); | ||||||
|         bool radiotext_AB_flag = m_bfmDemod->getRDSParser().m_radiotext_AB_flag; |         bool radiotext_AB_flag = m_bfmDemod->getRDSParser()->m_radiotext_AB_flag; | ||||||
| 
 | 
 | ||||||
|         if (!m_radiotext_AB_flag && radiotext_AB_flag) // B -> A transiition is start of new text
 |         if (!m_radiotext_AB_flag && radiotext_AB_flag) // B -> A transiition is start of new text
 | ||||||
|         { |         { | ||||||
| @ -734,7 +747,7 @@ void BFMDemodGUI::rdsUpdate(bool force) | |||||||
|             ui->go2PrevText->setText(oldText); |             ui->go2PrevText->setText(oldText); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 		ui->go2Text->setText(QString(m_bfmDemod->getRDSParser().m_g2_radiotext)); | 		ui->go2Text->setText(QString(m_bfmDemod->getRDSParser()->m_g2_radiotext)); | ||||||
|         m_radiotext_AB_flag = radiotext_AB_flag; |         m_radiotext_AB_flag = radiotext_AB_flag; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| @ -743,11 +756,11 @@ void BFMDemodGUI::rdsUpdate(bool force) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// G3 group
 | 	// G3 group
 | ||||||
| 	if (m_bfmDemod->getRDSParser().m_g3_updated || force) | 	if (m_bfmDemod->getRDSParser()->m_g3_updated || force) | ||||||
| 	{ | 	{ | ||||||
| 		ui->g03Label->setStyleSheet("QLabel { background-color : green; }"); | 		ui->g03Label->setStyleSheet("QLabel { background-color : green; }"); | ||||||
| 		ui->g03CountText->setNum((int) m_bfmDemod->getRDSParser().m_g3_count); | 		ui->g03CountText->setNum((int) m_bfmDemod->getRDSParser()->m_g3_count); | ||||||
| 		std::string g3str = str(boost::format("%02X%c %04X %04X") % m_bfmDemod->getRDSParser().m_g3_appGroup % (m_bfmDemod->getRDSParser().m_g3_groupB ? 'B' : 'A') % m_bfmDemod->getRDSParser().m_g3_message % m_bfmDemod->getRDSParser().m_g3_aid); | 		std::string g3str = str(boost::format("%02X%c %04X %04X") % m_bfmDemod->getRDSParser()->m_g3_appGroup % (m_bfmDemod->getRDSParser()->m_g3_groupB ? 'B' : 'A') % m_bfmDemod->getRDSParser()->m_g3_message % m_bfmDemod->getRDSParser()->m_g3_aid); | ||||||
| 		ui->g03Data->setText(QString(g3str.c_str())); | 		ui->g03Data->setText(QString(g3str.c_str())); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| @ -756,12 +769,12 @@ void BFMDemodGUI::rdsUpdate(bool force) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// G4 group
 | 	// G4 group
 | ||||||
| 	if (m_bfmDemod->getRDSParser().m_g4_updated || force) | 	if (m_bfmDemod->getRDSParser()->m_g4_updated || force) | ||||||
| 	{ | 	{ | ||||||
| 		ui->g04Label->setStyleSheet("QLabel { background-color : green; }"); | 		ui->g04Label->setStyleSheet("QLabel { background-color : green; }"); | ||||||
| 		ui->g04CountText->setNum((int) m_bfmDemod->getRDSParser().m_g4_count); | 		ui->g04CountText->setNum((int) m_bfmDemod->getRDSParser()->m_g4_count); | ||||||
| 		std::string time = str(boost::format("%4i-%02i-%02i %02i:%02i (%+.1fh)")\ | 		std::string time = str(boost::format("%4i-%02i-%02i %02i:%02i (%+.1fh)")\ | ||||||
| 			% (1900 + m_bfmDemod->getRDSParser().m_g4_year) % m_bfmDemod->getRDSParser().m_g4_month % m_bfmDemod->getRDSParser().m_g4_day % m_bfmDemod->getRDSParser().m_g4_hours % m_bfmDemod->getRDSParser().m_g4_minutes % m_bfmDemod->getRDSParser().m_g4_local_time_offset); | 			% (1900 + m_bfmDemod->getRDSParser()->m_g4_year) % m_bfmDemod->getRDSParser()->m_g4_month % m_bfmDemod->getRDSParser()->m_g4_day % m_bfmDemod->getRDSParser()->m_g4_hours % m_bfmDemod->getRDSParser()->m_g4_minutes % m_bfmDemod->getRDSParser()->m_g4_local_time_offset); | ||||||
| 	    ui->g04Time->setText(QString(time.c_str())); | 	    ui->g04Time->setText(QString(time.c_str())); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| @ -770,42 +783,42 @@ void BFMDemodGUI::rdsUpdate(bool force) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// G5 group
 | 	// G5 group
 | ||||||
| 	if (m_bfmDemod->getRDSParser().m_g5_updated || force) | 	if (m_bfmDemod->getRDSParser()->m_g5_updated || force) | ||||||
| 	{ | 	{ | ||||||
| 		ui->g05CountText->setNum((int) m_bfmDemod->getRDSParser().m_g5_count); | 		ui->g05CountText->setNum((int) m_bfmDemod->getRDSParser()->m_g5_count); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// G6 group
 | 	// G6 group
 | ||||||
| 	if (m_bfmDemod->getRDSParser().m_g6_updated || force) | 	if (m_bfmDemod->getRDSParser()->m_g6_updated || force) | ||||||
| 	{ | 	{ | ||||||
| 		ui->g06CountText->setNum((int) m_bfmDemod->getRDSParser().m_g6_count); | 		ui->g06CountText->setNum((int) m_bfmDemod->getRDSParser()->m_g6_count); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// G7 group
 | 	// G7 group
 | ||||||
| 	if (m_bfmDemod->getRDSParser().m_g7_updated || force) | 	if (m_bfmDemod->getRDSParser()->m_g7_updated || force) | ||||||
| 	{ | 	{ | ||||||
| 		ui->g07CountText->setNum((int) m_bfmDemod->getRDSParser().m_g7_count); | 		ui->g07CountText->setNum((int) m_bfmDemod->getRDSParser()->m_g7_count); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// G8 group
 | 	// G8 group
 | ||||||
| 	if (m_bfmDemod->getRDSParser().m_g8_updated || force) | 	if (m_bfmDemod->getRDSParser()->m_g8_updated || force) | ||||||
| 	{ | 	{ | ||||||
| 		ui->g08Label->setStyleSheet("QLabel { background-color : green; }"); | 		ui->g08Label->setStyleSheet("QLabel { background-color : green; }"); | ||||||
| 		ui->g08CountText->setNum((int) m_bfmDemod->getRDSParser().m_g8_count); | 		ui->g08CountText->setNum((int) m_bfmDemod->getRDSParser()->m_g8_count); | ||||||
| 
 | 
 | ||||||
| 		std::ostringstream os; | 		std::ostringstream os; | ||||||
| 		os << (m_bfmDemod->getRDSParser().m_g8_sign ? "-" : "+") << m_bfmDemod->getRDSParser().m_g8_extent + 1; | 		os << (m_bfmDemod->getRDSParser()->m_g8_sign ? "-" : "+") << m_bfmDemod->getRDSParser()->m_g8_extent + 1; | ||||||
| 		ui->g08Extent->setText(QString(os.str().c_str())); | 		ui->g08Extent->setText(QString(os.str().c_str())); | ||||||
| 		int event_line = RDSTMC::get_tmc_event_code_index(m_bfmDemod->getRDSParser().m_g8_event, 1); | 		int event_line = RDSTMC::get_tmc_event_code_index(m_bfmDemod->getRDSParser()->m_g8_event, 1); | ||||||
| 		ui->g08TMCEvent->setText(QString(RDSTMC::get_tmc_events(event_line, 1).c_str())); | 		ui->g08TMCEvent->setText(QString(RDSTMC::get_tmc_events(event_line, 1).c_str())); | ||||||
| 		QString pistring(str(boost::format("%04X") % m_bfmDemod->getRDSParser().m_g8_location).c_str()); | 		QString pistring(str(boost::format("%04X") % m_bfmDemod->getRDSParser()->m_g8_location).c_str()); | ||||||
| 		ui->g08Location->setText(pistring); | 		ui->g08Location->setText(pistring); | ||||||
| 
 | 
 | ||||||
| 		if (m_bfmDemod->getRDSParser().m_g8_label_index >= 0) { | 		if (m_bfmDemod->getRDSParser()->m_g8_label_index >= 0) { | ||||||
| 			ui->g08Description->setText(QString(m_bfmDemod->getRDSParser().label_descriptions[m_bfmDemod->getRDSParser().m_g8_label_index].c_str())); | 			ui->g08Description->setText(QString(m_bfmDemod->getRDSParser()->label_descriptions[m_bfmDemod->getRDSParser()->m_g8_label_index].c_str())); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		ui->g08Content->setNum(m_bfmDemod->getRDSParser().m_g8_content); | 		ui->g08Content->setNum(m_bfmDemod->getRDSParser()->m_g8_content); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @ -813,11 +826,11 @@ void BFMDemodGUI::rdsUpdate(bool force) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// G9 group
 | 	// G9 group
 | ||||||
| 	if (m_bfmDemod->getRDSParser().m_g9_updated || force) | 	if (m_bfmDemod->getRDSParser()->m_g9_updated || force) | ||||||
| 	{ | 	{ | ||||||
| 		ui->g09Label->setStyleSheet("QLabel { background-color : green; }"); | 		ui->g09Label->setStyleSheet("QLabel { background-color : green; }"); | ||||||
| 		ui->g09CountText->setNum((int) m_bfmDemod->getRDSParser().m_g9_count); | 		ui->g09CountText->setNum((int) m_bfmDemod->getRDSParser()->m_g9_count); | ||||||
| 		std::string g9str = str(boost::format("%02X %04X %04X %02X %04X") % m_bfmDemod->getRDSParser().m_g9_varA % m_bfmDemod->getRDSParser().m_g9_cA % m_bfmDemod->getRDSParser().m_g9_dA % m_bfmDemod->getRDSParser().m_g9_varB % m_bfmDemod->getRDSParser().m_g9_dB); | 		std::string g9str = str(boost::format("%02X %04X %04X %02X %04X") % m_bfmDemod->getRDSParser()->m_g9_varA % m_bfmDemod->getRDSParser()->m_g9_cA % m_bfmDemod->getRDSParser()->m_g9_dA % m_bfmDemod->getRDSParser()->m_g9_varB % m_bfmDemod->getRDSParser()->m_g9_dB); | ||||||
| 		ui->g09Data->setText(QString(g9str.c_str())); | 		ui->g09Data->setText(QString(g9str.c_str())); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| @ -826,18 +839,18 @@ void BFMDemodGUI::rdsUpdate(bool force) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// G14 group
 | 	// G14 group
 | ||||||
| 	if (m_bfmDemod->getRDSParser().m_g14_updated || force) | 	if (m_bfmDemod->getRDSParser()->m_g14_updated || force) | ||||||
| 	{ | 	{ | ||||||
| 		ui->g14CountText->setNum((int) m_bfmDemod->getRDSParser().m_g14_count); | 		ui->g14CountText->setNum((int) m_bfmDemod->getRDSParser()->m_g14_count); | ||||||
| 
 | 
 | ||||||
| 		if (m_bfmDemod->getRDSParser().m_g14_data_available) | 		if (m_bfmDemod->getRDSParser()->m_g14_data_available) | ||||||
| 		{ | 		{ | ||||||
| 			ui->g14Label->setStyleSheet("QLabel { background-color : green; }"); | 			ui->g14Label->setStyleSheet("QLabel { background-color : green; }"); | ||||||
| 			m_g14ComboIndex.clear(); | 			m_g14ComboIndex.clear(); | ||||||
| 			ui->g14ProgServiceNames->clear(); | 			ui->g14ProgServiceNames->clear(); | ||||||
| 
 | 
 | ||||||
| 			RDSParser::psns_map_t::iterator it = m_bfmDemod->getRDSParser().m_g14_program_service_names.begin(); | 			RDSParser::psns_map_t::iterator it = m_bfmDemod->getRDSParser()->m_g14_program_service_names.begin(); | ||||||
| 			const RDSParser::psns_map_t::iterator itEnd = m_bfmDemod->getRDSParser().m_g14_program_service_names.end(); | 			const RDSParser::psns_map_t::iterator itEnd = m_bfmDemod->getRDSParser()->m_g14_program_service_names.end(); | ||||||
| 			int i = 0; | 			int i = 0; | ||||||
| 
 | 
 | ||||||
| 			for (; it != itEnd; ++it, i++) | 			for (; it != itEnd; ++it, i++) | ||||||
| @ -853,7 +866,7 @@ void BFMDemodGUI::rdsUpdate(bool force) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	m_bfmDemod->getRDSParser().clearUpdateFlags(); | 	m_bfmDemod->getRDSParser()->clearUpdateFlags(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BFMDemodGUI::changeFrequency(qint64 f) | void BFMDemodGUI::changeFrequency(qint64 f) | ||||||
|  | |||||||
| @ -222,8 +222,10 @@ void BFMDemodSink::feed(const SampleVector::const_iterator& begin, const SampleV | |||||||
| 				{ | 				{ | ||||||
| 					std::size_t res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], std::min(m_audioBufferFill, m_audioBuffer.size())); | 					std::size_t res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], std::min(m_audioBufferFill, m_audioBuffer.size())); | ||||||
| 
 | 
 | ||||||
| 					if(res != m_audioBufferFill) { | 					if (res != m_audioBufferFill) | ||||||
|  |                     { | ||||||
| 						qDebug("BFMDemodSink::feed: %lu/%lu audio samples written", res, m_audioBufferFill); | 						qDebug("BFMDemodSink::feed: %lu/%lu audio samples written", res, m_audioBufferFill); | ||||||
|  |                         m_audioFifo.clear(); | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					m_audioBufferFill = 0; | 					m_audioBufferFill = 0; | ||||||
|  | |||||||
| @ -78,8 +78,6 @@ NFMDemod::NFMDemod(DeviceAPI *devieAPI) : | |||||||
|         this, |         this, | ||||||
|         &NFMDemod::handleIndexInDeviceSetChanged |         &NFMDemod::handleIndexInDeviceSetChanged | ||||||
|     ); |     ); | ||||||
| 
 |  | ||||||
|     start(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| NFMDemod::~NFMDemod() | NFMDemod::~NFMDemod() | ||||||
| @ -593,11 +591,11 @@ void NFMDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response | |||||||
|     getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples); |     getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples); | ||||||
| 
 | 
 | ||||||
|     response.getNfmDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg)); |     response.getNfmDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg)); | ||||||
|     int nbCtcssToneFrequencies; |  | ||||||
| 
 | 
 | ||||||
|     if (m_running) |     if (m_running) | ||||||
|     { |     { | ||||||
|         const Real *ctcssToneFrequencies = m_basebandSink->getCtcssToneSet(nbCtcssToneFrequencies); |         int nbCtcssToneFrequencies = CTCSSDetector::getNTones(); | ||||||
|  |         const Real *ctcssToneFrequencies = CTCSSDetector::getToneSet(); | ||||||
|         response.getNfmDemodReport()->setCtcssTone( |         response.getNfmDemodReport()->setCtcssTone( | ||||||
|             m_settings.m_ctcssOn ? |             m_settings.m_ctcssOn ? | ||||||
|                 m_settings.m_ctcssIndex < 0 ? |                 m_settings.m_ctcssIndex < 0 ? | ||||||
|  | |||||||
| @ -124,7 +124,6 @@ public: | |||||||
|             const QStringList& channelSettingsKeys, |             const QStringList& channelSettingsKeys, | ||||||
|             SWGSDRangel::SWGChannelSettings& response); |             SWGSDRangel::SWGChannelSettings& response); | ||||||
| 
 | 
 | ||||||
| 	const Real *getCtcssToneSet(int& nbTones) const { return m_running ? m_basebandSink->getCtcssToneSet(nbTones) : nullptr; } |  | ||||||
| 	bool getSquelchOpen() const { return m_running && m_basebandSink->getSquelchOpen(); } | 	bool getSquelchOpen() const { return m_running && m_basebandSink->getSquelchOpen(); } | ||||||
| 
 | 
 | ||||||
|     void getMagSqLevels(double& avg, double& peak, int& nbSamples) |     void getMagSqLevels(double& avg, double& peak, int& nbSamples) | ||||||
|  | |||||||
| @ -66,7 +66,6 @@ public: | |||||||
|     int getChannelSampleRate() const; |     int getChannelSampleRate() const; | ||||||
|     void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_sink.getMagSqLevels(avg, peak, nbSamples); } |     void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_sink.getMagSqLevels(avg, peak, nbSamples); } | ||||||
|     bool getSquelchOpen() const { return m_sink.getSquelchOpen(); } |     bool getSquelchOpen() const { return m_sink.getSquelchOpen(); } | ||||||
|     const Real *getCtcssToneSet(int& nbTones) const { return m_sink.getCtcssToneSet(nbTones); } |  | ||||||
|     void setMessageQueueToGUI(MessageQueue *messageQueue) { m_sink.setMessageQueueToGUI(messageQueue); } |     void setMessageQueueToGUI(MessageQueue *messageQueue) { m_sink.setMessageQueueToGUI(messageQueue); } | ||||||
|     int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } |     int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } | ||||||
|     void setBasebandSampleRate(int sampleRate); |     void setBasebandSampleRate(int sampleRate); | ||||||
|  | |||||||
| @ -407,13 +407,16 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban | |||||||
| 
 | 
 | ||||||
|     ui->channelSpacing->setCurrentIndex(NFMDemodSettings::getChannelSpacingIndex(12500)); |     ui->channelSpacing->setCurrentIndex(NFMDemodSettings::getChannelSpacingIndex(12500)); | ||||||
| 
 | 
 | ||||||
|     int ctcss_nbTones; |     int ctcss_nbTones = CTCSSDetector::getNTones(); | ||||||
|     const Real *ctcss_tones = m_nfmDemod->getCtcssToneSet(ctcss_nbTones); |     const Real *ctcss_tones = CTCSSDetector::getToneSet(); | ||||||
| 
 | 
 | ||||||
|     ui->ctcss->addItem("--"); |     ui->ctcss->addItem("--"); | ||||||
| 
 | 
 | ||||||
|     for (int i=0; i<ctcss_nbTones; i++) { |     if (ctcss_tones) | ||||||
|         ui->ctcss->addItem(QString("%1").arg(ctcss_tones[i])); |     { | ||||||
|  |         for (int i=0; i<ctcss_nbTones; i++) { | ||||||
|  |             ui->ctcss->addItem(QString("%1").arg(ctcss_tones[i])); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ui->dcsOn->setChecked(m_settings.m_dcsOn); |     ui->dcsOn->setChecked(m_settings.m_dcsOn); | ||||||
|  | |||||||
| @ -45,11 +45,6 @@ public: | |||||||
| 
 | 
 | ||||||
|     virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end); |     virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end); | ||||||
| 
 | 
 | ||||||
|     const Real *getCtcssToneSet(int& nbTones) const { |  | ||||||
|         nbTones = m_ctcssDetector.getNTones(); |  | ||||||
|         return m_ctcssDetector.getToneSet(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     bool getSquelchOpen() const { return m_squelchOpen; } |     bool getSquelchOpen() const { return m_squelchOpen; } | ||||||
| 
 | 
 | ||||||
|     void getMagSqLevels(double& avg, double& peak, int& nbSamples) |     void getMagSqLevels(double& avg, double& peak, int& nbSamples) | ||||||
|  | |||||||
| @ -54,6 +54,8 @@ const char* const SSBDemod::m_channelId = "SSBDemod"; | |||||||
| SSBDemod::SSBDemod(DeviceAPI *deviceAPI) : | SSBDemod::SSBDemod(DeviceAPI *deviceAPI) : | ||||||
|         ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), |         ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), | ||||||
|         m_deviceAPI(deviceAPI), |         m_deviceAPI(deviceAPI), | ||||||
|  |         m_thread(nullptr), | ||||||
|  |         m_basebandSink(nullptr), | ||||||
|         m_running(false), |         m_running(false), | ||||||
|         m_spectrumVis(SDR_RX_SCALEF), |         m_spectrumVis(SDR_RX_SCALEF), | ||||||
|         m_basebandSampleRate(0) |         m_basebandSampleRate(0) | ||||||
| @ -78,8 +80,6 @@ SSBDemod::SSBDemod(DeviceAPI *deviceAPI) : | |||||||
|         this, |         this, | ||||||
|         &SSBDemod::handleIndexInDeviceSetChanged |         &SSBDemod::handleIndexInDeviceSetChanged | ||||||
|     ); |     ); | ||||||
| 
 |  | ||||||
|     start(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SSBDemod::~SSBDemod() | SSBDemod::~SSBDemod() | ||||||
|  | |||||||
| @ -202,6 +202,7 @@ void SSBDemodGUI::on_agc_toggled(bool checked) | |||||||
| { | { | ||||||
|     m_settings.m_agc = checked; |     m_settings.m_agc = checked; | ||||||
|     applySettings(); |     applySettings(); | ||||||
|  |     displayAGC(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SSBDemodGUI::on_agcClamping_toggled(bool checked) | void SSBDemodGUI::on_agcClamping_toggled(bool checked) | ||||||
| @ -466,10 +467,26 @@ void SSBDemodGUI::applySettings(bool force) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | uint32_t SSBDemodGUI::getValidAudioSampleRate() const | ||||||
|  | { | ||||||
|  |     // When not running, m_ssbDemod->getAudioSampleRate() will return 0, but we
 | ||||||
|  |     // want a valid value to initialise the GUI, to allow a user to preselect settings
 | ||||||
|  |     int sr = m_ssbDemod->getAudioSampleRate(); | ||||||
|  |     if (sr == 0) | ||||||
|  |     { | ||||||
|  |         if (m_audioSampleRate > 0) { | ||||||
|  |             sr = m_audioSampleRate; | ||||||
|  |         } else { | ||||||
|  |             sr = 48000; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return sr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| unsigned int SSBDemodGUI::spanLog2Max() | unsigned int SSBDemodGUI::spanLog2Max() | ||||||
| { | { | ||||||
|     unsigned int spanLog2 = 0; |     unsigned int spanLog2 = 0; | ||||||
|     for (; m_ssbDemod->getAudioSampleRate() / (1<<spanLog2) >= 1000; spanLog2++); |     for (; getValidAudioSampleRate() / (1<<spanLog2) >= 1000; spanLog2++); | ||||||
|     return spanLog2 == 0 ? 0 : spanLog2-1; |     return spanLog2 == 0 ? 0 : spanLog2-1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -481,10 +498,10 @@ void SSBDemodGUI::applyBandwidths(unsigned int spanLog2, bool force) | |||||||
|     ui->spanLog2->setMaximum(limit); |     ui->spanLog2->setMaximum(limit); | ||||||
|     bool dsb = ui->dsb->isChecked(); |     bool dsb = ui->dsb->isChecked(); | ||||||
|     //int spanLog2 = ui->spanLog2->value();
 |     //int spanLog2 = ui->spanLog2->value();
 | ||||||
|     m_spectrumRate = m_ssbDemod->getAudioSampleRate() / (1<<spanLog2); |     m_spectrumRate = getValidAudioSampleRate() / (1<<spanLog2); | ||||||
|     int bw = ui->BW->value(); |     int bw = ui->BW->value(); | ||||||
|     int lw = ui->lowCut->value(); |     int lw = ui->lowCut->value(); | ||||||
|     int bwMax = m_ssbDemod->getAudioSampleRate() / (100*(1<<spanLog2)); |     int bwMax = getValidAudioSampleRate() / (100*(1<<spanLog2)); | ||||||
|     int tickInterval = m_spectrumRate / 1200; |     int tickInterval = m_spectrumRate / 1200; | ||||||
|     tickInterval = tickInterval == 0 ? 1 : tickInterval; |     tickInterval = tickInterval == 0 ? 1 : tickInterval; | ||||||
| 
 | 
 | ||||||
| @ -636,6 +653,7 @@ void SSBDemodGUI::displaySettings() | |||||||
|     ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency()); |     ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency()); | ||||||
| 
 | 
 | ||||||
|     ui->agc->setChecked(m_settings.m_agc); |     ui->agc->setChecked(m_settings.m_agc); | ||||||
|  |     displayAGC(); | ||||||
|     ui->agcClamping->setChecked(m_settings.m_agcClamping); |     ui->agcClamping->setChecked(m_settings.m_agcClamping); | ||||||
|     ui->dnr->setChecked(m_settings.m_dnr); |     ui->dnr->setChecked(m_settings.m_dnr); | ||||||
|     ui->audioBinaural->setChecked(m_settings.m_audioBinaural); |     ui->audioBinaural->setChecked(m_settings.m_audioBinaural); | ||||||
| @ -694,6 +712,18 @@ void SSBDemodGUI::displaySettings() | |||||||
|     blockApplySettings(false); |     blockApplySettings(false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void SSBDemodGUI::displayAGC() | ||||||
|  | { | ||||||
|  |     // Disable controls only valid when AGC is enabled
 | ||||||
|  |     ui->agcClamping->setEnabled(m_settings.m_agc); | ||||||
|  |     ui->agcTimeLog2->setEnabled(m_settings.m_agc); | ||||||
|  |     ui->agcTimeText->setEnabled(m_settings.m_agc); | ||||||
|  |     ui->agcPowerThreshold->setEnabled(m_settings.m_agc); | ||||||
|  |     ui->agcPowerThresholdText->setEnabled(m_settings.m_agc); | ||||||
|  |     ui->agcThresholdGate->setEnabled(m_settings.m_agc); | ||||||
|  |     ui->agcThresholdGateText->setEnabled(m_settings.m_agc); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void SSBDemodGUI::displayAGCPowerThreshold(int value) | void SSBDemodGUI::displayAGCPowerThreshold(int value) | ||||||
| { | { | ||||||
|     if (value == SSBDemodSettings::m_minPowerThresholdDB) |     if (value == SSBDemodSettings::m_minPowerThresholdDB) | ||||||
|  | |||||||
| @ -102,11 +102,13 @@ private: | |||||||
| 	void applyBandwidths(unsigned int spanLog2, bool force = false); | 	void applyBandwidths(unsigned int spanLog2, bool force = false); | ||||||
|     unsigned int spanLog2Max(); |     unsigned int spanLog2Max(); | ||||||
| 	void displaySettings(); | 	void displaySettings(); | ||||||
|  | 	void displayAGC(); | ||||||
| 	void displayAGCPowerThreshold(int value); | 	void displayAGCPowerThreshold(int value); | ||||||
|     void displayAGCThresholdGate(int value); |     void displayAGCThresholdGate(int value); | ||||||
| 	bool handleMessage(const Message& message); | 	bool handleMessage(const Message& message); | ||||||
|     void makeUIConnections(); |     void makeUIConnections(); | ||||||
|     void updateAbsoluteCenterFrequency(); |     void updateAbsoluteCenterFrequency(); | ||||||
|  | 	uint32_t getValidAudioSampleRate() const; | ||||||
| 
 | 
 | ||||||
| 	void leaveEvent(QEvent*); | 	void leaveEvent(QEvent*); | ||||||
| 	void enterEvent(EnterEventType*); | 	void enterEvent(EnterEventType*); | ||||||
|  | |||||||
| @ -881,6 +881,13 @@ | |||||||
|         </property> |         </property> | ||||||
|        </widget> |        </widget> | ||||||
|       </item> |       </item> | ||||||
|  |       <item> | ||||||
|  |        <widget class="Line" name="line_7"> | ||||||
|  |         <property name="orientation"> | ||||||
|  |          <enum>Qt::Vertical</enum> | ||||||
|  |         </property> | ||||||
|  |        </widget> | ||||||
|  |       </item> | ||||||
|       <item> |       <item> | ||||||
|        <widget class="QDial" name="agcTimeLog2"> |        <widget class="QDial" name="agcTimeLog2"> | ||||||
|         <property name="maximumSize"> |         <property name="maximumSize"> | ||||||
| @ -925,6 +932,13 @@ | |||||||
|         </property> |         </property> | ||||||
|        </widget> |        </widget> | ||||||
|       </item> |       </item> | ||||||
|  |       <item> | ||||||
|  |        <widget class="Line" name="line_5"> | ||||||
|  |         <property name="orientation"> | ||||||
|  |          <enum>Qt::Vertical</enum> | ||||||
|  |         </property> | ||||||
|  |        </widget> | ||||||
|  |       </item> | ||||||
|       <item> |       <item> | ||||||
|        <widget class="QDial" name="agcPowerThreshold"> |        <widget class="QDial" name="agcPowerThreshold"> | ||||||
|         <property name="maximumSize"> |         <property name="maximumSize"> | ||||||
| @ -969,6 +983,13 @@ | |||||||
|         </property> |         </property> | ||||||
|        </widget> |        </widget> | ||||||
|       </item> |       </item> | ||||||
|  |       <item> | ||||||
|  |        <widget class="Line" name="line_6"> | ||||||
|  |         <property name="orientation"> | ||||||
|  |          <enum>Qt::Vertical</enum> | ||||||
|  |         </property> | ||||||
|  |        </widget> | ||||||
|  |       </item> | ||||||
|       <item> |       <item> | ||||||
|        <widget class="QDial" name="agcThresholdGate"> |        <widget class="QDial" name="agcThresholdGate"> | ||||||
|         <property name="maximumSize"> |         <property name="maximumSize"> | ||||||
| @ -1126,12 +1147,24 @@ | |||||||
|    <extends>QToolButton</extends> |    <extends>QToolButton</extends> | ||||||
|    <header>gui/buttonswitch.h</header> |    <header>gui/buttonswitch.h</header> | ||||||
|   </customwidget> |   </customwidget> | ||||||
|  |   <customwidget> | ||||||
|  |    <class>ValueDialZ</class> | ||||||
|  |    <extends>QWidget</extends> | ||||||
|  |    <header>gui/valuedialz.h</header> | ||||||
|  |    <container>1</container> | ||||||
|  |   </customwidget> | ||||||
|   <customwidget> |   <customwidget> | ||||||
|    <class>RollupContents</class> |    <class>RollupContents</class> | ||||||
|    <extends>QWidget</extends> |    <extends>QWidget</extends> | ||||||
|    <header>gui/rollupcontents.h</header> |    <header>gui/rollupcontents.h</header> | ||||||
|    <container>1</container> |    <container>1</container> | ||||||
|   </customwidget> |   </customwidget> | ||||||
|  |   <customwidget> | ||||||
|  |    <class>LevelMeterSignalDB</class> | ||||||
|  |    <extends>QWidget</extends> | ||||||
|  |    <header>gui/levelmeter.h</header> | ||||||
|  |    <container>1</container> | ||||||
|  |   </customwidget> | ||||||
|   <customwidget> |   <customwidget> | ||||||
|    <class>GLSpectrum</class> |    <class>GLSpectrum</class> | ||||||
|    <extends>QWidget</extends> |    <extends>QWidget</extends> | ||||||
| @ -1144,18 +1177,6 @@ | |||||||
|    <header>gui/glspectrumgui.h</header> |    <header>gui/glspectrumgui.h</header> | ||||||
|    <container>1</container> |    <container>1</container> | ||||||
|   </customwidget> |   </customwidget> | ||||||
|   <customwidget> |  | ||||||
|    <class>ValueDialZ</class> |  | ||||||
|    <extends>QWidget</extends> |  | ||||||
|    <header>gui/valuedialz.h</header> |  | ||||||
|    <container>1</container> |  | ||||||
|   </customwidget> |  | ||||||
|   <customwidget> |  | ||||||
|    <class>LevelMeterSignalDB</class> |  | ||||||
|    <extends>QWidget</extends> |  | ||||||
|    <header>gui/levelmeter.h</header> |  | ||||||
|    <container>1</container> |  | ||||||
|   </customwidget> |  | ||||||
|   <customwidget> |   <customwidget> | ||||||
|    <class>TickedSlider</class> |    <class>TickedSlider</class> | ||||||
|    <extends>QSlider</extends> |    <extends>QSlider</extends> | ||||||
|  | |||||||
| @ -78,8 +78,6 @@ VORDemod::VORDemod(DeviceAPI *deviceAPI) : | |||||||
|         this, |         this, | ||||||
|         &VORDemod::handleIndexInDeviceSetChanged |         &VORDemod::handleIndexInDeviceSetChanged | ||||||
|     ); |     ); | ||||||
| 
 |  | ||||||
|     start(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VORDemod::~VORDemod() | VORDemod::~VORDemod() | ||||||
|  | |||||||
| @ -79,7 +79,6 @@ WFMDemod::WFMDemod(DeviceAPI* deviceAPI) : | |||||||
|         this, |         this, | ||||||
|         &WFMDemod::handleIndexInDeviceSetChanged |         &WFMDemod::handleIndexInDeviceSetChanged | ||||||
|     ); |     ); | ||||||
|     start(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| WFMDemod::~WFMDemod() | WFMDemod::~WFMDemod() | ||||||
|  | |||||||
| @ -46,12 +46,12 @@ public: | |||||||
|     bool analyze(Real *sample); // input signal sample
 |     bool analyze(Real *sample); // input signal sample
 | ||||||
| 
 | 
 | ||||||
|     // get the number of defined tones.
 |     // get the number of defined tones.
 | ||||||
|     int getNTones() const { |     static int getNTones() { | ||||||
|     	return CTCSSFrequencies::m_nbFreqs; |     	return CTCSSFrequencies::m_nbFreqs; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // get the tone set
 |     // get the tone set
 | ||||||
|     const Real *getToneSet() const { |     static const Real *getToneSet() { | ||||||
|     	return CTCSSFrequencies::m_Freqs; |     	return CTCSSFrequencies::m_Freqs; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user