diff --git a/plugins/channelrx/demodais/aisdemod.cpp b/plugins/channelrx/demodais/aisdemod.cpp index 9ff21f792..aa831cadf 100644 --- a/plugins/channelrx/demodais/aisdemod.cpp +++ b/plugins/channelrx/demodais/aisdemod.cpp @@ -64,6 +64,7 @@ AISDemod::AISDemod(DeviceAPI *deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } AISDemod::~AISDemod() @@ -180,6 +181,13 @@ bool AISDemod::handleMessage(const Message& cmd) return true; } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "AISDemod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; + } else { return false; @@ -279,6 +287,25 @@ bool AISDemod::deserialize(const QByteArray& data) } } +void AISDemod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + AISDemodSettings::AISDEMOD_CHANNEL_SAMPLE_RATE + ); + (*it)->push(msg); + } + } +} + int AISDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -498,3 +525,15 @@ void AISDemod::networkManagerFinished(QNetworkReply *reply) reply->deleteLater(); } + +void AISDemod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channelrx/demodais/aisdemod.h b/plugins/channelrx/demodais/aisdemod.h index 8739f9331..63cc9a061 100644 --- a/plugins/channelrx/demodais/aisdemod.h +++ b/plugins/channelrx/demodais/aisdemod.h @@ -165,6 +165,7 @@ private: QNetworkRequest m_networkRequest; void applySettings(const AISDemodSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void webapiReverseSendSettings(QList& channelSettingsKeys, const AISDemodSettings& settings, bool force); void webapiFormatChannelSettings( QList& channelSettingsKeys, @@ -175,7 +176,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); - + void handleChannelMessages(); }; #endif // INCLUDE_AISDEMOD_H diff --git a/plugins/channelrx/demodais/aisdemodbaseband.cpp b/plugins/channelrx/demodais/aisdemodbaseband.cpp index f4d6971dc..423f2caf1 100644 --- a/plugins/channelrx/demodais/aisdemodbaseband.cpp +++ b/plugins/channelrx/demodais/aisdemodbaseband.cpp @@ -160,7 +160,7 @@ void AISDemodBaseband::applySettings(const AISDemodSettings& settings, bool forc { if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) { - m_channelizer->setChannelization(AISDEMOD_CHANNEL_SAMPLE_RATE, settings.m_inputFrequencyOffset); + m_channelizer->setChannelization(AISDemodSettings::AISDEMOD_CHANNEL_SAMPLE_RATE, settings.m_inputFrequencyOffset); m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset()); } diff --git a/plugins/channelrx/demodais/aisdemodsettings.h b/plugins/channelrx/demodais/aisdemodsettings.h index 609b85d11..fe0e5d6df 100644 --- a/plugins/channelrx/demodais/aisdemodsettings.h +++ b/plugins/channelrx/demodais/aisdemodsettings.h @@ -61,6 +61,8 @@ struct AISDemodSettings int m_messageColumnIndexes[AISDEMOD_MESSAGE_COLUMNS];//!< How the columns are ordered in the table int m_messageColumnSizes[AISDEMOD_MESSAGE_COLUMNS]; //!< Size of the columns in the table + static const int AISDEMOD_CHANNEL_SAMPLE_RATE = 57600; //!< 6x 9600 baud rate (use even multiple so Gausian filter has odd number of taps) + AISDemodSettings(); void resetToDefaults(); void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; } diff --git a/plugins/channelrx/demodais/aisdemodsink.cpp b/plugins/channelrx/demodais/aisdemodsink.cpp index d2985c7aa..ac1fcbcba 100644 --- a/plugins/channelrx/demodais/aisdemodsink.cpp +++ b/plugins/channelrx/demodais/aisdemodsink.cpp @@ -36,7 +36,7 @@ AISDemodSink::AISDemodSink(AISDemod *aisDemod) : m_scopeSink(nullptr), m_aisDemod(aisDemod), - m_channelSampleRate(AISDEMOD_CHANNEL_SAMPLE_RATE), + m_channelSampleRate(AISDemodSettings::AISDEMOD_CHANNEL_SAMPLE_RATE), m_channelFrequencyOffset(0), m_magsqSum(0.0f), m_magsqPeak(0.0f), @@ -410,13 +410,13 @@ void AISDemodSink::applyChannelSettings(int channelSampleRate, int channelFreque if ((m_channelSampleRate != channelSampleRate) || force) { m_interpolator.create(16, channelSampleRate, m_settings.m_rfBandwidth / 2.2); - m_interpolatorDistance = (Real) channelSampleRate / (Real) AISDEMOD_CHANNEL_SAMPLE_RATE; + m_interpolatorDistance = (Real) channelSampleRate / (Real) AISDemodSettings::AISDEMOD_CHANNEL_SAMPLE_RATE; m_interpolatorDistanceRemain = m_interpolatorDistance; } m_channelSampleRate = channelSampleRate; m_channelFrequencyOffset = channelFrequencyOffset; - m_samplesPerSymbol = AISDEMOD_CHANNEL_SAMPLE_RATE / m_settings.m_baud; + m_samplesPerSymbol = AISDemodSettings::AISDEMOD_CHANNEL_SAMPLE_RATE / m_settings.m_baud; qDebug() << "AISDemodSink::applyChannelSettings: m_samplesPerSymbol: " << m_samplesPerSymbol; } @@ -428,18 +428,18 @@ void AISDemodSink::applySettings(const AISDemodSettings& settings, bool force) if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) { m_interpolator.create(16, m_channelSampleRate, settings.m_rfBandwidth / 2.2); - m_interpolatorDistance = (Real) m_channelSampleRate / (Real) AISDEMOD_CHANNEL_SAMPLE_RATE; + m_interpolatorDistance = (Real) m_channelSampleRate / (Real) AISDemodSettings::AISDEMOD_CHANNEL_SAMPLE_RATE; m_interpolatorDistanceRemain = m_interpolatorDistance; - m_lowpass.create(301, AISDEMOD_CHANNEL_SAMPLE_RATE, settings.m_rfBandwidth / 2.0f); + m_lowpass.create(301, AISDemodSettings::AISDEMOD_CHANNEL_SAMPLE_RATE, settings.m_rfBandwidth / 2.0f); } if ((settings.m_fmDeviation != m_settings.m_fmDeviation) || force) { - m_phaseDiscri.setFMScaling(AISDEMOD_CHANNEL_SAMPLE_RATE / (2.0f * settings.m_fmDeviation)); + m_phaseDiscri.setFMScaling(AISDemodSettings::AISDEMOD_CHANNEL_SAMPLE_RATE / (2.0f * settings.m_fmDeviation)); } if ((settings.m_baud != m_settings.m_baud) || force) { - m_samplesPerSymbol = AISDEMOD_CHANNEL_SAMPLE_RATE / settings.m_baud; + m_samplesPerSymbol = AISDemodSettings::AISDEMOD_CHANNEL_SAMPLE_RATE / settings.m_baud; qDebug() << "ISDemodSink::applySettings: m_samplesPerSymbol: " << m_samplesPerSymbol << " baud " << settings.m_baud; m_pulseShape.create(0.5, 3, m_samplesPerSymbol); diff --git a/plugins/channelrx/demodais/aisdemodsink.h b/plugins/channelrx/demodais/aisdemodsink.h index 8526551cf..0a1ddda3b 100644 --- a/plugins/channelrx/demodais/aisdemodsink.h +++ b/plugins/channelrx/demodais/aisdemodsink.h @@ -41,9 +41,6 @@ #include #include -// 6x 9600 baud rate (use even multiple so Gausian filter has odd number of taps) -#define AISDEMOD_CHANNEL_SAMPLE_RATE 57600 - #define AISDEMOD_MAX_BYTES (3+1+126+2+1+1) class ChannelAPI; diff --git a/plugins/channelrx/demodam/amdemod.cpp b/plugins/channelrx/demodam/amdemod.cpp index a47d73a9d..9f612260b 100644 --- a/plugins/channelrx/demodam/amdemod.cpp +++ b/plugins/channelrx/demodam/amdemod.cpp @@ -63,6 +63,7 @@ AMDemod::AMDemod(DeviceAPI *deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } AMDemod::~AMDemod() @@ -135,6 +136,13 @@ bool AMDemod::handleMessage(const Message& cmd) m_basebandSink->getInputMessageQueue()->push(rep); return true; + } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "AMDemod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; } else { @@ -258,6 +266,25 @@ bool AMDemod::deserialize(const QByteArray& data) } } +void AMDemod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + getAudioSampleRate() + ); + (*it)->push(msg); + } + } +} + int AMDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -540,3 +567,15 @@ void AMDemod::networkManagerFinished(QNetworkReply *reply) reply->deleteLater(); } + +void AMDemod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channelrx/demodam/amdemod.h b/plugins/channelrx/demodam/amdemod.h index 55cf713f1..10bddb460 100644 --- a/plugins/channelrx/demodam/amdemod.h +++ b/plugins/channelrx/demodam/amdemod.h @@ -140,6 +140,7 @@ private: QNetworkRequest m_networkRequest; void applySettings(const AMDemodSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); void webapiReverseSendSettings(QList& channelSettingsKeys, const AMDemodSettings& settings, bool force); void sendChannelSettings( @@ -157,7 +158,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); - + void handleChannelMessages(); }; #endif // INCLUDE_AMDEMOD_H diff --git a/plugins/channelrx/demoddab/dabdemod.cpp b/plugins/channelrx/demoddab/dabdemod.cpp index c0d6361bd..e0bb1e4c7 100644 --- a/plugins/channelrx/demoddab/dabdemod.cpp +++ b/plugins/channelrx/demoddab/dabdemod.cpp @@ -74,6 +74,7 @@ DABDemod::DABDemod(DeviceAPI *deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } DABDemod::~DABDemod() @@ -257,6 +258,13 @@ bool DABDemod::handleMessage(const Message& cmd) return true; } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "DABDemod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; + } else { return false; @@ -345,6 +353,25 @@ bool DABDemod::deserialize(const QByteArray& data) } } +void DABDemod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + getAudioSampleRate() + ); + (*it)->push(msg); + } + } +} + int DABDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -550,3 +577,15 @@ void DABDemod::networkManagerFinished(QNetworkReply *reply) reply->deleteLater(); } + +void DABDemod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channelrx/demoddab/dabdemod.h b/plugins/channelrx/demoddab/dabdemod.h index e4366c9f3..25fd8faaf 100644 --- a/plugins/channelrx/demoddab/dabdemod.h +++ b/plugins/channelrx/demoddab/dabdemod.h @@ -369,6 +369,7 @@ public: }*/ uint32_t getNumberOfDeviceStreams() const; + int getAudioSampleRate() const { return m_basebandSink->getAudioSampleRate(); } static const char * const m_channelIdURI; static const char * const m_channelId; @@ -385,6 +386,7 @@ private: QNetworkRequest m_networkRequest; void applySettings(const DABDemodSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void webapiReverseSendSettings(QList& channelSettingsKeys, const DABDemodSettings& settings, bool force); void webapiFormatChannelSettings( QList& channelSettingsKeys, @@ -395,7 +397,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); - + void handleChannelMessages(); }; #endif // INCLUDE_DABDEMOD_H diff --git a/plugins/channelrx/demoddab/dabdemodbaseband.h b/plugins/channelrx/demoddab/dabdemodbaseband.h index 983574691..51c92ae08 100644 --- a/plugins/channelrx/demoddab/dabdemodbaseband.h +++ b/plugins/channelrx/demoddab/dabdemodbaseband.h @@ -74,6 +74,7 @@ public: void setChannel(ChannelAPI *channel); double getMagSq() const { return m_sink.getMagSq(); } bool isRunning() const { return m_running; } + int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } private: SampleSinkFifo m_sampleFifo; diff --git a/plugins/channelrx/demoddab/dabdemodsink.cpp b/plugins/channelrx/demoddab/dabdemodsink.cpp index 86bd3b394..7e8135e34 100644 --- a/plugins/channelrx/demoddab/dabdemodsink.cpp +++ b/plugins/channelrx/demoddab/dabdemodsink.cpp @@ -640,6 +640,19 @@ void DABDemodSink::applyAudioSampleRate(int sampleRate) m_audioFifo.setSize(sampleRate); + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(m_channel, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(m_channel, sampleRate); + (*it)->push(msg); + } + } + m_audioSampleRate = sampleRate; } diff --git a/plugins/channelrx/demoddsd/dsddemod.cpp b/plugins/channelrx/demoddsd/dsddemod.cpp index 6fa5a6bb0..915eb33f9 100644 --- a/plugins/channelrx/demoddsd/dsddemod.cpp +++ b/plugins/channelrx/demoddsd/dsddemod.cpp @@ -69,6 +69,7 @@ DSDDemod::DSDDemod(DeviceAPI *deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } DSDDemod::~DSDDemod() @@ -134,6 +135,13 @@ bool DSDDemod::handleMessage(const Message& cmd) m_basebandSink->getInputMessageQueue()->push(rep); return true; + } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "DSDDemod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; } else { @@ -284,6 +292,25 @@ bool DSDDemod::deserialize(const QByteArray& data) } } +void DSDDemod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + getAudioSampleRate() + ); + (*it)->push(msg); + } + } +} + int DSDDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -647,3 +674,15 @@ void DSDDemod::networkManagerFinished(QNetworkReply *reply) reply->deleteLater(); } + +void DSDDemod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channelrx/demoddsd/dsddemod.h b/plugins/channelrx/demoddsd/dsddemod.h index daaf0482b..1e6aa8527 100644 --- a/plugins/channelrx/demoddsd/dsddemod.h +++ b/plugins/channelrx/demoddsd/dsddemod.h @@ -138,6 +138,7 @@ private: static const int m_udpBlockSize; void applySettings(const DSDDemodSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); void webapiReverseSendSettings(QList& channelSettingsKeys, const DSDDemodSettings& settings, bool force); void sendChannelSettings( @@ -155,7 +156,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); - + void handleChannelMessages(); }; #endif // INCLUDE_DSDDEMOD_H diff --git a/plugins/channelrx/demodnfm/nfmdemod.cpp b/plugins/channelrx/demodnfm/nfmdemod.cpp index a920e9887..5658f60d9 100644 --- a/plugins/channelrx/demodnfm/nfmdemod.cpp +++ b/plugins/channelrx/demodnfm/nfmdemod.cpp @@ -68,6 +68,7 @@ NFMDemod::NFMDemod(DeviceAPI *devieAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } NFMDemod::~NFMDemod() @@ -132,6 +133,13 @@ bool NFMDemod::handleMessage(const Message& cmd) return true; } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "NFMDemod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; + } else { return false; @@ -269,6 +277,25 @@ bool NFMDemod::deserialize(const QByteArray& data) return success; } +void NFMDemod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + getAudioSampleRate() + ); + (*it)->push(msg); + } + } +} + int NFMDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -583,3 +610,15 @@ void NFMDemod::networkManagerFinished(QNetworkReply *reply) reply->deleteLater(); } + +void NFMDemod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channelrx/demodnfm/nfmdemod.h b/plugins/channelrx/demodnfm/nfmdemod.h index 8b4cf1eb6..dad9dc389 100644 --- a/plugins/channelrx/demodnfm/nfmdemod.h +++ b/plugins/channelrx/demodnfm/nfmdemod.h @@ -138,6 +138,7 @@ private: static const int m_udpBlockSize; void applySettings(const NFMDemodSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); void webapiReverseSendSettings(QList& channelSettingsKeys, const NFMDemodSettings& settings, bool force); void sendChannelSettings( @@ -155,6 +156,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); + void handleChannelMessages(); }; #endif // INCLUDE_NFMDEMOD_H diff --git a/plugins/channelrx/demodpacket/packetdemod.cpp b/plugins/channelrx/demodpacket/packetdemod.cpp index ea7dbf386..8b9d8ee4f 100644 --- a/plugins/channelrx/demodpacket/packetdemod.cpp +++ b/plugins/channelrx/demodpacket/packetdemod.cpp @@ -64,6 +64,7 @@ PacketDemod::PacketDemod(DeviceAPI *deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } PacketDemod::~PacketDemod() @@ -177,6 +178,13 @@ bool PacketDemod::handleMessage(const Message& cmd) return true; } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "PacketDemod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; + } else { return false; @@ -243,6 +251,25 @@ void PacketDemod::applySettings(const PacketDemodSettings& settings, bool force) m_settings = settings; } +void PacketDemod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE + ); + (*it)->push(msg); + } + } +} + QByteArray PacketDemod::serialize() const { return m_settings.serialize(); @@ -470,3 +497,15 @@ void PacketDemod::networkManagerFinished(QNetworkReply *reply) reply->deleteLater(); } + +void PacketDemod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channelrx/demodpacket/packetdemod.h b/plugins/channelrx/demodpacket/packetdemod.h index c005da56c..e15d2c840 100644 --- a/plugins/channelrx/demodpacket/packetdemod.h +++ b/plugins/channelrx/demodpacket/packetdemod.h @@ -138,6 +138,7 @@ private: QNetworkRequest m_networkRequest; void applySettings(const PacketDemodSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void webapiReverseSendSettings(QList& channelSettingsKeys, const PacketDemodSettings& settings, bool force); void webapiFormatChannelSettings( QList& channelSettingsKeys, @@ -148,6 +149,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); + void handleChannelMessages(); }; diff --git a/plugins/channelrx/demodpacket/packetdemodbaseband.cpp b/plugins/channelrx/demodpacket/packetdemodbaseband.cpp index 6975b1396..264978c37 100644 --- a/plugins/channelrx/demodpacket/packetdemodbaseband.cpp +++ b/plugins/channelrx/demodpacket/packetdemodbaseband.cpp @@ -159,7 +159,7 @@ void PacketDemodBaseband::applySettings(const PacketDemodSettings& settings, boo { if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) { - m_channelizer->setChannelization(PACKETDEMOD_CHANNEL_SAMPLE_RATE, settings.m_inputFrequencyOffset); + m_channelizer->setChannelization(PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE, settings.m_inputFrequencyOffset); m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset()); } diff --git a/plugins/channelrx/demodpacket/packetdemodsettings.h b/plugins/channelrx/demodpacket/packetdemodsettings.h index 9f90cc1bd..33386837c 100644 --- a/plugins/channelrx/demodpacket/packetdemodsettings.h +++ b/plugins/channelrx/demodpacket/packetdemodsettings.h @@ -53,6 +53,9 @@ struct PacketDemodSettings int m_columnIndexes[PACKETDEMOD_COLUMNS];//!< How the columns are ordered in the table int m_columnSizes[PACKETDEMOD_COLUMNS]; //!< Size of the columns in the table + static const int PACKETDEMOD_CHANNEL_BANDWIDTH = 9600; + static const int PACKETDEMOD_CHANNEL_SAMPLE_RATE = 38400; // Must be integer multiple of m_baud=1200 + PacketDemodSettings(); void resetToDefaults(); void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; } diff --git a/plugins/channelrx/demodpacket/packetdemodsink.cpp b/plugins/channelrx/demodpacket/packetdemodsink.cpp index 3b644ecf7..92adaa93e 100644 --- a/plugins/channelrx/demodpacket/packetdemodsink.cpp +++ b/plugins/channelrx/demodpacket/packetdemodsink.cpp @@ -32,7 +32,7 @@ PacketDemodSink::PacketDemodSink(PacketDemod *packetDemod) : m_packetDemod(packetDemod), - m_channelSampleRate(PACKETDEMOD_CHANNEL_SAMPLE_RATE), + m_channelSampleRate(PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE), m_channelFrequencyOffset(0), m_magsqSum(0.0f), m_magsqPeak(0.0f), @@ -136,7 +136,7 @@ void PacketDemodSink::processOneSample(Complex &ci) // Look for edge if (sample != m_samplePrev) { - m_syncCount = PACKETDEMOD_CHANNEL_SAMPLE_RATE/m_settings.m_baud/2; + m_syncCount = PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE/m_settings.m_baud/2; } else { @@ -235,7 +235,7 @@ void PacketDemodSink::processOneSample(Complex &ci) m_bitCount = 0; } } - m_syncCount = PACKETDEMOD_CHANNEL_SAMPLE_RATE/m_settings.m_baud; + m_syncCount = PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE/m_settings.m_baud; } } m_samplePrev = sample; @@ -277,7 +277,7 @@ void PacketDemodSink::applyChannelSettings(int channelSampleRate, int channelFre if ((m_channelSampleRate != channelSampleRate) || force) { m_interpolator.create(16, channelSampleRate, m_settings.m_rfBandwidth / 2.2); - m_interpolatorDistance = (Real) channelSampleRate / (Real) PACKETDEMOD_CHANNEL_SAMPLE_RATE; + m_interpolatorDistance = (Real) channelSampleRate / (Real) PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE; m_interpolatorDistanceRemain = m_interpolatorDistance; } @@ -293,13 +293,13 @@ void PacketDemodSink::applySettings(const PacketDemodSettings& settings, bool fo if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) { m_interpolator.create(16, m_channelSampleRate, settings.m_rfBandwidth / 2.2); - m_interpolatorDistance = (Real) m_channelSampleRate / (Real) PACKETDEMOD_CHANNEL_SAMPLE_RATE; + m_interpolatorDistance = (Real) m_channelSampleRate / (Real) PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE; m_interpolatorDistanceRemain = m_interpolatorDistance; - m_lowpass.create(301, PACKETDEMOD_CHANNEL_SAMPLE_RATE, settings.m_rfBandwidth / 2.0f); + m_lowpass.create(301, PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE, settings.m_rfBandwidth / 2.0f); } if ((settings.m_fmDeviation != m_settings.m_fmDeviation) || force) { - m_phaseDiscri.setFMScaling(PACKETDEMOD_CHANNEL_SAMPLE_RATE / (2.0f * settings.m_fmDeviation)); + m_phaseDiscri.setFMScaling(PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE / (2.0f * settings.m_fmDeviation)); } if (force) @@ -307,7 +307,7 @@ void PacketDemodSink::applySettings(const PacketDemodSettings& settings, bool fo delete[] m_f1; delete[] m_f0; delete[] m_corrBuf; - m_correlationLength = PACKETDEMOD_CHANNEL_SAMPLE_RATE/settings.m_baud; + m_correlationLength = PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE/settings.m_baud; m_f1 = new Complex[m_correlationLength](); m_f0 = new Complex[m_correlationLength](); m_corrBuf = new Complex[m_correlationLength](); @@ -319,12 +319,12 @@ void PacketDemodSink::applySettings(const PacketDemodSettings& settings, bool fo { m_f0[i] = Complex(cos(f0), sin(f0)); m_f1[i] = Complex(cos(f1), sin(f1)); - f0 += 2.0f*(Real)M_PI*2200.0f/PACKETDEMOD_CHANNEL_SAMPLE_RATE; - f1 += 2.0f*(Real)M_PI*1200.0f/PACKETDEMOD_CHANNEL_SAMPLE_RATE; + f0 += 2.0f*(Real)M_PI*2200.0f/PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE; + f1 += 2.0f*(Real)M_PI*1200.0f/PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE; } - m_lowpassF1.create(301, PACKETDEMOD_CHANNEL_SAMPLE_RATE, settings.m_baud * 1.1f); - m_lowpassF0.create(301, PACKETDEMOD_CHANNEL_SAMPLE_RATE, settings.m_baud * 1.1f); + m_lowpassF1.create(301, PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE, settings.m_baud * 1.1f); + m_lowpassF0.create(301, PacketDemodSettings::PACKETDEMOD_CHANNEL_SAMPLE_RATE, settings.m_baud * 1.1f); m_samplePrev = 0; m_syncCount = 0; m_symbolPrev = 0; diff --git a/plugins/channelrx/demodpacket/packetdemodsink.h b/plugins/channelrx/demodpacket/packetdemodsink.h index c207f838f..9db2d722f 100644 --- a/plugins/channelrx/demodpacket/packetdemodsink.h +++ b/plugins/channelrx/demodpacket/packetdemodsink.h @@ -37,10 +37,6 @@ #include #include -#define PACKETDEMOD_CHANNEL_BANDWIDTH 9600 -// Must be integer multiple of m_baud=1200 -#define PACKETDEMOD_CHANNEL_SAMPLE_RATE 38400 - class ChannelAPI; class PacketDemod; diff --git a/plugins/channelrx/demodssb/ssbdemod.cpp b/plugins/channelrx/demodssb/ssbdemod.cpp index 2908cb8bb..031abdbda 100644 --- a/plugins/channelrx/demodssb/ssbdemod.cpp +++ b/plugins/channelrx/demodssb/ssbdemod.cpp @@ -68,6 +68,7 @@ SSBDemod::SSBDemod(DeviceAPI *deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } SSBDemod::~SSBDemod() @@ -132,6 +133,13 @@ bool SSBDemod::handleMessage(const Message& cmd) return true; } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "SSBDemod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; + } else { return false; @@ -280,6 +288,25 @@ bool SSBDemod::deserialize(const QByteArray& data) } } +void SSBDemod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + getAudioSampleRate() + ); + (*it)->push(msg); + } + } +} + int SSBDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -599,3 +626,15 @@ void SSBDemod::networkManagerFinished(QNetworkReply *reply) reply->deleteLater(); } + +void SSBDemod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channelrx/demodssb/ssbdemod.h b/plugins/channelrx/demodssb/ssbdemod.h index 19d969225..ccca81f81 100644 --- a/plugins/channelrx/demodssb/ssbdemod.h +++ b/plugins/channelrx/demodssb/ssbdemod.h @@ -142,6 +142,7 @@ private: QNetworkRequest m_networkRequest; void applySettings(const SSBDemodSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); void webapiReverseSendSettings(QList& channelSettingsKeys, const SSBDemodSettings& settings, bool force); void sendChannelSettings( @@ -159,6 +160,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); + void handleChannelMessages(); }; #endif // INCLUDE_SSBDEMOD_H diff --git a/plugins/channelrx/demodwfm/wfmdemod.cpp b/plugins/channelrx/demodwfm/wfmdemod.cpp index 64deec0f3..3d644b043 100644 --- a/plugins/channelrx/demodwfm/wfmdemod.cpp +++ b/plugins/channelrx/demodwfm/wfmdemod.cpp @@ -69,6 +69,7 @@ WFMDemod::WFMDemod(DeviceAPI* deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } WFMDemod::~WFMDemod() @@ -134,6 +135,13 @@ bool WFMDemod::handleMessage(const Message& cmd) return true; } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "WFMDemod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; + } else { return false; @@ -245,6 +253,25 @@ bool WFMDemod::deserialize(const QByteArray& data) } } +void WFMDemod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + getAudioSampleRate() + ); + (*it)->push(msg); + } + } +} + int WFMDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -507,3 +534,15 @@ void WFMDemod::networkManagerFinished(QNetworkReply *reply) reply->deleteLater(); } + +void WFMDemod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channelrx/demodwfm/wfmdemod.h b/plugins/channelrx/demodwfm/wfmdemod.h index 8f3d48f3f..dc6bfc748 100644 --- a/plugins/channelrx/demodwfm/wfmdemod.h +++ b/plugins/channelrx/demodwfm/wfmdemod.h @@ -134,7 +134,7 @@ private: static const int m_udpBlockSize; void applySettings(const WFMDemodSettings& settings, bool force = false); - + void sendSampleRateToDemodAnalyzer(); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); void webapiReverseSendSettings(QList& channelSettingsKeys, const WFMDemodSettings& settings, bool force); void sendChannelSettings( @@ -152,6 +152,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); + void handleChannelMessages(); }; #endif // INCLUDE_WFMDEMOD_H diff --git a/plugins/channeltx/modais/aismod.cpp b/plugins/channeltx/modais/aismod.cpp index 2e9717671..697c06df0 100644 --- a/plugins/channeltx/modais/aismod.cpp +++ b/plugins/channeltx/modais/aismod.cpp @@ -73,6 +73,7 @@ AISMod::AISMod(DeviceAPI *deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } AISMod::~AISMod() @@ -134,6 +135,13 @@ bool AISMod::handleMessage(const Message& cmd) m_basebandSource->getInputMessageQueue()->push(rep); return true; } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "AISMod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; + } else { return false; @@ -340,6 +348,25 @@ bool AISMod::deserialize(const QByteArray& data) return success; } +void AISMod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + AISModSettings::AISMOD_SAMPLE_RATE + ); + (*it)->push(msg); + } + } +} + int AISMod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -822,3 +849,15 @@ void AISMod::udpRx() m_basebandSource->getInputMessageQueue()->push(msg); } } + +void AISMod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channeltx/modais/aismod.h b/plugins/channeltx/modais/aismod.h index e93d4ff4c..ff9bf55f2 100644 --- a/plugins/channeltx/modais/aismod.h +++ b/plugins/channeltx/modais/aismod.h @@ -184,6 +184,7 @@ private: QUdpSocket *m_udpSocket; void applySettings(const AISModSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); void webapiReverseSendSettings(QList& channelSettingsKeys, const AISModSettings& settings, bool force); void sendChannelSettings( @@ -204,6 +205,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); void udpRx(); + void handleChannelMessages(); }; diff --git a/plugins/channeltx/modais/aismodgui.cpp b/plugins/channeltx/modais/aismodgui.cpp index 28a3d6e9a..843aec16a 100644 --- a/plugins/channeltx/modais/aismodgui.cpp +++ b/plugins/channeltx/modais/aismodgui.cpp @@ -516,7 +516,7 @@ AISModGUI::AISModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam ui->scopeGUI->changeTrigger(0, triggerData); ui->scopeGUI->focusOnTrigger(0); // re-focus to take changes into account in the GUI - m_scopeVis->setLiveRate(AISMOD_SAMPLE_RATE); + m_scopeVis->setLiveRate(AISModSettings::AISMOD_SAMPLE_RATE); //m_scopeVis->setFreeRun(false); // FIXME: add method rather than call m_scopeVis->configure() m_spectrumVis = m_aisMod->getSpectrumVis(); @@ -524,7 +524,7 @@ AISModGUI::AISModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam // Extra /2 here because SSB? ui->glSpectrum->setCenterFrequency(0); - ui->glSpectrum->setSampleRate(AISMOD_SAMPLE_RATE); + ui->glSpectrum->setSampleRate(AISModSettings::AISMOD_SAMPLE_RATE); ui->glSpectrum->setSsbSpectrum(true); ui->glSpectrum->setDisplayCurrent(true); ui->glSpectrum->setLsbDisplay(false); diff --git a/plugins/channeltx/modais/aismodsettings.h b/plugins/channeltx/modais/aismodsettings.h index 75061ad8d..dced1fe75 100644 --- a/plugins/channeltx/modais/aismodsettings.h +++ b/plugins/channeltx/modais/aismodsettings.h @@ -67,6 +67,10 @@ struct AISModSettings QString m_udpAddress; uint16_t m_udpPort; + // Sample rate is multiple of 9600 baud rate (use even multiple so Gausian filter has odd number of taps) + // Is there any benefit to having this higher? + static const int AISMOD_SAMPLE_RATE = (9600*6); + AISModSettings(); void resetToDefaults(); void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; } diff --git a/plugins/channeltx/modais/aismodsource.cpp b/plugins/channeltx/modais/aismodsource.cpp index 9083a8ad1..a61111ab0 100644 --- a/plugins/channeltx/modais/aismodsource.cpp +++ b/plugins/channeltx/modais/aismodsource.cpp @@ -28,7 +28,7 @@ #include "channel/channelapi.h" AISModSource::AISModSource() : - m_channelSampleRate(AISMOD_SAMPLE_RATE), + m_channelSampleRate(AISModSettings::AISMOD_SAMPLE_RATE), m_channelFrequencyOffset(0), m_fmPhase(0.0), m_spectrumSink(nullptr), @@ -238,7 +238,7 @@ void AISModSource::modulateSample() { // Wait before retransmitting m_state = wait; - m_waitCounter = m_settings.m_repeatDelay * AISMOD_SAMPLE_RATE; + m_waitCounter = m_settings.m_repeatDelay * AISModSettings::AISMOD_SAMPLE_RATE; } else { @@ -298,17 +298,17 @@ void AISModSource::applySettings(const AISModSettings& settings, bool force) if ((settings.m_bt != m_settings.m_bt) || (settings.m_symbolSpan != m_settings.m_symbolSpan) || (settings.m_baud != m_settings.m_baud) || force) { qDebug() << "AISModSource::applySettings: Recreating pulse shaping filter: " - << " SampleRate:" << AISMOD_SAMPLE_RATE + << " SampleRate:" << AISModSettings::AISMOD_SAMPLE_RATE << " bt: " << settings.m_bt << " symbolSpan: " << settings.m_symbolSpan << " baud:" << settings.m_baud; - m_pulseShape.create(settings.m_bt, settings.m_symbolSpan, AISMOD_SAMPLE_RATE/settings.m_baud); + m_pulseShape.create(settings.m_bt, settings.m_symbolSpan, AISModSettings::AISMOD_SAMPLE_RATE/settings.m_baud); } m_settings = settings; // Precalculate FM sensensity and linear gain to save doing it in the loop - m_samplesPerSymbol = AISMOD_SAMPLE_RATE / m_settings.m_baud; + m_samplesPerSymbol = AISModSettings::AISMOD_SAMPLE_RATE / m_settings.m_baud; Real modIndex = m_settings.m_fmDeviation / (Real)m_settings.m_baud; m_phaseSensitivity = 2.0f * M_PI * modIndex / (Real)m_samplesPerSymbol; m_linearGain = powf(10.0f, m_settings.m_gain/20.0f); @@ -330,8 +330,8 @@ void AISModSource::applyChannelSettings(int channelSampleRate, int channelFreque if ((m_channelSampleRate != channelSampleRate) || force) { m_interpolatorDistanceRemain = 0; - m_interpolatorDistance = (Real) AISMOD_SAMPLE_RATE / (Real) channelSampleRate; - m_interpolator.create(48, AISMOD_SAMPLE_RATE, m_settings.m_rfBandwidth / 2.2, 3.0); + m_interpolatorDistance = (Real) AISModSettings::AISMOD_SAMPLE_RATE / (Real) channelSampleRate; + m_interpolator.create(48, AISModSettings::AISMOD_SAMPLE_RATE, m_settings.m_rfBandwidth / 2.2, 3.0); } m_channelSampleRate = channelSampleRate; diff --git a/plugins/channeltx/modais/aismodsource.h b/plugins/channeltx/modais/aismodsource.h index b8a2a1579..edf65e2b7 100644 --- a/plugins/channeltx/modais/aismodsource.h +++ b/plugins/channeltx/modais/aismodsource.h @@ -43,10 +43,6 @@ #define AIS_TRAIN 0x55 #define AIS_FLAG 0x7e -// Sample rate is multiple of 9600 baud rate (use even multiple so Gausian filter has odd number of taps) -// Is there any benefit to having this higher? -#define AISMOD_SAMPLE_RATE (9600*6) - class ScopeVis; class BasebandSampleSink; class ChannelAPI; diff --git a/plugins/channeltx/modam/ammod.cpp b/plugins/channeltx/modam/ammod.cpp index 992f283b2..d406b4eea 100644 --- a/plugins/channeltx/modam/ammod.cpp +++ b/plugins/channeltx/modam/ammod.cpp @@ -75,6 +75,7 @@ AMMod::AMMod(DeviceAPI *deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } AMMod::~AMMod() @@ -176,6 +177,13 @@ bool AMMod::handleMessage(const Message& cmd) return true; } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "AMMod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; + } else { return false; @@ -334,6 +342,25 @@ bool AMMod::deserialize(const QByteArray& data) } } +void AMMod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + getAudioSampleRate() + ); + (*it)->push(msg); + } + } +} + int AMMod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -694,3 +721,15 @@ int AMMod::getFeedbackAudioSampleRate() const { return m_basebandSource->getFeedbackAudioSampleRate(); } + +void AMMod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channeltx/modam/ammod.h b/plugins/channeltx/modam/ammod.h index f66b91715..785404035 100644 --- a/plugins/channeltx/modam/ammod.h +++ b/plugins/channeltx/modam/ammod.h @@ -255,6 +255,7 @@ private: QNetworkRequest m_networkRequest; void applySettings(const AMModSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void openFileStream(); void seekFileStream(int seekPercentage); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); @@ -275,6 +276,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); + void handleChannelMessages(); }; diff --git a/plugins/channeltx/modnfm/nfmmod.cpp b/plugins/channeltx/modnfm/nfmmod.cpp index e8f434b62..7f7936649 100644 --- a/plugins/channeltx/modnfm/nfmmod.cpp +++ b/plugins/channeltx/modnfm/nfmmod.cpp @@ -76,6 +76,7 @@ NFMMod::NFMMod(DeviceAPI *deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } NFMMod::~NFMMod() @@ -208,6 +209,13 @@ bool NFMMod::handleMessage(const Message& cmd) return true; } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "NFMMod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; + } else { return false; @@ -381,6 +389,25 @@ bool NFMMod::deserialize(const QByteArray& data) return success; } +void NFMMod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + getAudioSampleRate() + ); + (*it)->push(msg); + } + } +} + int NFMMod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -785,3 +812,15 @@ int NFMMod::getFeedbackAudioSampleRate() const { return m_basebandSource->getFeedbackAudioSampleRate(); } + +void NFMMod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channeltx/modnfm/nfmmod.h b/plugins/channeltx/modnfm/nfmmod.h index 8ef28fac4..50b29a807 100644 --- a/plugins/channeltx/modnfm/nfmmod.h +++ b/plugins/channeltx/modnfm/nfmmod.h @@ -255,6 +255,7 @@ private: QNetworkRequest m_networkRequest; void applySettings(const NFMModSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void openFileStream(); void seekFileStream(int seekPercentage); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); @@ -275,6 +276,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); + void handleChannelMessages(); }; diff --git a/plugins/channeltx/modpacket/packetmod.cpp b/plugins/channeltx/modpacket/packetmod.cpp index ad13ed7d5..1e8e19485 100644 --- a/plugins/channeltx/modpacket/packetmod.cpp +++ b/plugins/channeltx/modpacket/packetmod.cpp @@ -78,6 +78,7 @@ PacketMod::PacketMod(DeviceAPI *deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } PacketMod::~PacketMod() @@ -140,6 +141,13 @@ bool PacketMod::handleMessage(const Message& cmd) return true; } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "PacketMod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; + } else { return false; @@ -405,6 +413,25 @@ bool PacketMod::deserialize(const QByteArray& data) return success; } +void PacketMod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + getSourceChannelSampleRate() + ); + (*it)->push(msg); + } + } +} + int PacketMod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -982,6 +1009,11 @@ uint32_t PacketMod::getNumberOfDeviceStreams() const return m_deviceAPI->getNbSinkStreams(); } +int PacketMod::getSourceChannelSampleRate() const +{ + return m_basebandSource->getSourceChannelSampleRate(); +} + void PacketMod::openUDP(const PacketModSettings& settings) { closeUDP(); @@ -1012,3 +1044,15 @@ void PacketMod::udpRx() m_basebandSource->getInputMessageQueue()->push(msg); } } + +void PacketMod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channeltx/modpacket/packetmod.h b/plugins/channeltx/modpacket/packetmod.h index e040661d9..625868839 100644 --- a/plugins/channeltx/modpacket/packetmod.h +++ b/plugins/channeltx/modpacket/packetmod.h @@ -171,6 +171,7 @@ public: double getMagSq() const; void setLevelMeter(QObject *levelMeter); uint32_t getNumberOfDeviceStreams() const; + int getSourceChannelSampleRate() const; static const char* const m_channelIdURI; static const char* const m_channelId; @@ -197,6 +198,7 @@ private: QUdpSocket *m_udpSocket; void applySettings(const PacketModSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); void webapiReverseSendSettings(QList& channelSettingsKeys, const PacketModSettings& settings, bool force); void sendChannelSettings( @@ -217,6 +219,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); void udpRx(); + void handleChannelMessages(); }; diff --git a/plugins/channeltx/modpacket/packetmodbaseband.h b/plugins/channeltx/modpacket/packetmodbaseband.h index 1ae98d066..df7231a24 100644 --- a/plugins/channeltx/modpacket/packetmodbaseband.h +++ b/plugins/channeltx/modpacket/packetmodbaseband.h @@ -67,6 +67,7 @@ public: int getChannelSampleRate() const; void setSpectrumSampleSink(BasebandSampleSink* sampleSink) { m_source.setSpectrumSink(sampleSink); } void setChannel(ChannelAPI *channel); + int getSourceChannelSampleRate() const { return m_source.getChannelSampleRate(); } signals: /** diff --git a/plugins/channeltx/modpacket/packetmodsource.h b/plugins/channeltx/modpacket/packetmodsource.h index abd548dfd..c7e3aa9fc 100644 --- a/plugins/channeltx/modpacket/packetmodsource.h +++ b/plugins/channeltx/modpacket/packetmodsource.h @@ -71,6 +71,7 @@ public: void addTXPacket(QByteArray data); void encodePacket(uint8_t *packet, int packet_length, uint8_t *crc_start, uint8_t *packet_end); void setChannel(ChannelAPI *channel) { m_channel = channel; } + int getChannelSampleRate() const { return m_channelSampleRate; } private: int m_channelSampleRate; diff --git a/plugins/channeltx/modssb/ssbmod.cpp b/plugins/channeltx/modssb/ssbmod.cpp index 5092bb0c7..1a4f3f9d6 100644 --- a/plugins/channeltx/modssb/ssbmod.cpp +++ b/plugins/channeltx/modssb/ssbmod.cpp @@ -77,6 +77,7 @@ SSBMod::SSBMod(DeviceAPI *deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } SSBMod::~SSBMod() @@ -173,6 +174,13 @@ bool SSBMod::handleMessage(const Message& cmd) return true; } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "SSBMod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; + } else { return false; @@ -358,6 +366,25 @@ bool SSBMod::deserialize(const QByteArray& data) } } +void SSBMod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + getAudioSampleRate() + ); + (*it)->push(msg); + } + } +} + int SSBMod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -779,3 +806,15 @@ uint32_t SSBMod::getNumberOfDeviceStreams() const { return m_deviceAPI->getNbSinkStreams(); } + +void SSBMod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channeltx/modssb/ssbmod.h b/plugins/channeltx/modssb/ssbmod.h index bb5e2806b..92dd20e69 100644 --- a/plugins/channeltx/modssb/ssbmod.h +++ b/plugins/channeltx/modssb/ssbmod.h @@ -259,6 +259,7 @@ private: QNetworkRequest m_networkRequest; void applySettings(const SSBModSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void openFileStream(); void seekFileStream(int seekPercentage); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); @@ -279,6 +280,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); + void handleChannelMessages(); }; diff --git a/plugins/channeltx/modwfm/wfmmod.cpp b/plugins/channeltx/modwfm/wfmmod.cpp index 464633777..dcbac3bd2 100644 --- a/plugins/channeltx/modwfm/wfmmod.cpp +++ b/plugins/channeltx/modwfm/wfmmod.cpp @@ -74,6 +74,7 @@ WFMMod::WFMMod(DeviceAPI *deviceAPI) : m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + connect(&m_channelMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessages())); } WFMMod::~WFMMod() @@ -169,6 +170,13 @@ bool WFMMod::handleMessage(const Message& cmd) return true; } + else if (MainCore::MsgChannelDemodQuery::match(cmd)) + { + qDebug() << "WFMMod::handleMessage: MsgChannelDemodQuery"; + sendSampleRateToDemodAnalyzer(); + + return true; + } else { return false; @@ -320,6 +328,25 @@ bool WFMMod::deserialize(const QByteArray& data) } } +void WFMMod::sendSampleRateToDemodAnalyzer() +{ + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create( + this, + getAudioSampleRate() + ); + (*it)->push(msg); + } + } +} + int WFMMod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) @@ -689,3 +716,15 @@ int WFMMod::getFeedbackAudioSampleRate() const { return m_basebandSource->getFeedbackAudioSampleRate(); } + +void WFMMod::handleChannelMessages() +{ + Message* message; + + while ((message = m_channelMessageQueue.pop()) != nullptr) + { + if (handleMessage(*message)) { + delete message; + } + } +} diff --git a/plugins/channeltx/modwfm/wfmmod.h b/plugins/channeltx/modwfm/wfmmod.h index 9f4a01c29..0db306b1f 100644 --- a/plugins/channeltx/modwfm/wfmmod.h +++ b/plugins/channeltx/modwfm/wfmmod.h @@ -267,6 +267,7 @@ private: static const int m_levelNbSamples; void applySettings(const WFMModSettings& settings, bool force = false); + void sendSampleRateToDemodAnalyzer(); void openFileStream(); void seekFileStream(int seekPercentage); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); @@ -287,6 +288,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); + void handleChannelMessages(); }; diff --git a/plugins/feature/demodanalyzer/demodanalyzer.cpp b/plugins/feature/demodanalyzer/demodanalyzer.cpp index 962bcbc42..c8b1f14bf 100644 --- a/plugins/feature/demodanalyzer/demodanalyzer.cpp +++ b/plugins/feature/demodanalyzer/demodanalyzer.cpp @@ -24,6 +24,7 @@ #include "SWGFeatureActions.h" #include "SWGDeviceState.h" +#include "dsp/dspcommands.h" #include "dsp/dspengine.h" #include "dsp/datafifo.h" #include "dsp/dspdevicesourceengine.h" @@ -149,6 +150,8 @@ bool DemodAnalyzer::handleMessage(const Message& cmd) MsgSelectChannel& cfg = (MsgSelectChannel&) cmd; ChannelAPI *selectedChannel = cfg.getChannel(); setChannel(selectedChannel); + MainCore::MsgChannelDemodQuery *msg = MainCore::MsgChannelDemodQuery::create(); + selectedChannel->getChannelMessageQueue()->push(msg); return true; } @@ -160,6 +163,10 @@ bool DemodAnalyzer::handleMessage(const Message& cmd) if (report.getChannelAPI() == m_selectedChannel) { m_sampleRate = report.getSampleRate(); + m_scopeVis.setLiveRate(m_sampleRate); + + DSPSignalNotification *msg = new DSPSignalNotification(0, m_sampleRate); + m_spectrumVis.getInputMessageQueue()->push(msg); if (m_dataFifo) { m_dataFifo->setSize(2*m_sampleRate); diff --git a/plugins/feature/demodanalyzer/readme.md b/plugins/feature/demodanalyzer/readme.md index 69f2b6c8e..76ede3c98 100644 --- a/plugins/feature/demodanalyzer/readme.md +++ b/plugins/feature/demodanalyzer/readme.md @@ -6,14 +6,18 @@ This plugin can be used to analyze the real demodulated signal from some Rx chan Rx plugins are: + - AIS demodulator - AM demodulator + - DAB demodulator - DSD (FM digital voice) demodulator - NFM demodulator + - Packer demodulator - SSB demodulator - WFM demodulator Tx plugins are: + - AIS modulator - AM modulator - NFM modulator - Packet modulator @@ -55,7 +59,7 @@ Use this combo to select which channel to use for display. Channel is selected u

A.4: (Re)apply channel selection

-Applies or re-applies channel selection (A.3) so that the channel gets effectively connected to the analyzer and signal is displayed. +Applies or re-applies channel selection (A.3) so that the channel gets effectively connected to the analyzer and signal is displayed. This will update the sample rate.

A.5: Decimation by a power of two

diff --git a/sdrbase/channel/channelapi.h b/sdrbase/channel/channelapi.h index 2ebf71076..9c504d429 100644 --- a/sdrbase/channel/channelapi.h +++ b/sdrbase/channel/channelapi.h @@ -28,9 +28,9 @@ #include "export.h" #include "pipes/pipeendpoint.h" +#include "util/messagequeue.h" class DeviceAPI; -class MessageQueue; namespace SWGSDRangel { @@ -64,6 +64,7 @@ public: virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; } MessageQueue *getMessageQueueToGUI() { return m_guiMessageQueue; } + MessageQueue *getChannelMessageQueue() { return &m_channelMessageQueue; } //!< Get the queue for plugin communication /** * API adapter for the channel settings GET requests @@ -130,7 +131,8 @@ public: virtual qint64 getStreamCenterFrequency(int streamIndex, bool sinkElseSource) const = 0; protected: - MessageQueue *m_guiMessageQueue; //!< Input message queue to the GUI + MessageQueue *m_guiMessageQueue; //!< Input message queue to the GUI + MessageQueue m_channelMessageQueue; //!< Input message queue for inter plugin communication private: StreamType m_streamType; diff --git a/sdrbase/maincore.cpp b/sdrbase/maincore.cpp index c84adfc0c..7d6b842d9 100644 --- a/sdrbase/maincore.cpp +++ b/sdrbase/maincore.cpp @@ -48,6 +48,7 @@ MESSAGE_CLASS_DEFINITION(MainCore::MsgDeleteFeature, Message) MESSAGE_CLASS_DEFINITION(MainCore::MsgChannelReport, Message) MESSAGE_CLASS_DEFINITION(MainCore::MsgChannelSettings, Message) MESSAGE_CLASS_DEFINITION(MainCore::MsgChannelDemodReport, Message) +MESSAGE_CLASS_DEFINITION(MainCore::MsgChannelDemodQuery, Message) MESSAGE_CLASS_DEFINITION(MainCore::MsgMapItem, Message) MESSAGE_CLASS_DEFINITION(MainCore::MsgPacket, Message) MESSAGE_CLASS_DEFINITION(MainCore::MsgTargetAzimuthElevation, Message) diff --git a/sdrbase/maincore.h b/sdrbase/maincore.h index 1fc77834d..5eb665d2c 100644 --- a/sdrbase/maincore.h +++ b/sdrbase/maincore.h @@ -441,6 +441,20 @@ public: { } }; + class SDRBASE_API MsgChannelDemodQuery : public Message { + MESSAGE_CLASS_DECLARATION + + public: + static MsgChannelDemodQuery* create() { + return new MsgChannelDemodQuery(); + } + + private: + MsgChannelDemodQuery() : + Message() + { } + }; + class SDRBASE_API MsgChannelDemodReport : public Message { MESSAGE_CLASS_DECLARATION