1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-17 05:41:56 -05:00

Demod Analyzer: fixed sample rate handling. Fixes #931

This commit is contained in:
f4exb 2021-06-29 21:47:27 +02:00
parent a57c856a26
commit 0d4da317b3
49 changed files with 667 additions and 49 deletions

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -165,6 +165,7 @@ private:
QNetworkRequest m_networkRequest;
void applySettings(const AISDemodSettings& settings, bool force = false);
void sendSampleRateToDemodAnalyzer();
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const AISDemodSettings& settings, bool force);
void webapiFormatChannelSettings(
QList<QString>& channelSettingsKeys,
@ -175,7 +176,7 @@ private:
private slots:
void networkManagerFinished(QNetworkReply *reply);
void handleChannelMessages();
};
#endif // INCLUDE_AISDEMOD_H

View File

@ -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());
}

View File

@ -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; }

View File

@ -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);

View File

@ -41,9 +41,6 @@
#include <iostream>
#include <fstream>
// 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;

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -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<QString>& 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

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -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<QString>& channelSettingsKeys, const DABDemodSettings& settings, bool force);
void webapiFormatChannelSettings(
QList<QString>& channelSettingsKeys,
@ -395,7 +397,7 @@ private:
private slots:
void networkManagerFinished(QNetworkReply *reply);
void handleChannelMessages();
};
#endif // INCLUDE_DABDEMOD_H

View File

@ -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;

View File

@ -640,6 +640,19 @@ void DABDemodSink::applyAudioSampleRate(int sampleRate)
m_audioFifo.setSize(sampleRate);
QList<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(m_channel, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::iterator it = messageQueues->begin();
for (; it != messageQueues->end(); ++it)
{
MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(m_channel, sampleRate);
(*it)->push(msg);
}
}
m_audioSampleRate = sampleRate;
}

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -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<QString>& 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

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -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<QString>& 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

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -138,6 +138,7 @@ private:
QNetworkRequest m_networkRequest;
void applySettings(const PacketDemodSettings& settings, bool force = false);
void sendSampleRateToDemodAnalyzer();
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const PacketDemodSettings& settings, bool force);
void webapiFormatChannelSettings(
QList<QString>& channelSettingsKeys,
@ -148,6 +149,7 @@ private:
private slots:
void networkManagerFinished(QNetworkReply *reply);
void handleChannelMessages();
};

View File

@ -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());
}

View File

@ -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; }

View File

@ -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;

View File

@ -37,10 +37,6 @@
#include <iostream>
#include <fstream>
#define PACKETDEMOD_CHANNEL_BANDWIDTH 9600
// Must be integer multiple of m_baud=1200
#define PACKETDEMOD_CHANNEL_SAMPLE_RATE 38400
class ChannelAPI;
class PacketDemod;

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -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<QString>& 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

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -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<QString>& 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

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -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<QString>& channelSettingsKeys, const AISModSettings& settings, bool force);
void sendChannelSettings(
@ -204,6 +205,7 @@ private:
private slots:
void networkManagerFinished(QNetworkReply *reply);
void udpRx();
void handleChannelMessages();
};

View File

@ -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);

View File

@ -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; }

View File

@ -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;

View File

@ -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;

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -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();
};

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -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();
};

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -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<QString>& channelSettingsKeys, const PacketModSettings& settings, bool force);
void sendChannelSettings(
@ -217,6 +219,7 @@ private:
private slots:
void networkManagerFinished(QNetworkReply *reply);
void udpRx();
void handleChannelMessages();
};

View File

@ -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:
/**

View File

@ -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;

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -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();
};

View File

@ -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<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(this, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::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;
}
}
}

View File

@ -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();
};

View File

@ -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);

View File

@ -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
<h3>A.4: (Re)apply channel selection</h3>
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.
<h3>A.5: Decimation by a power of two</h3>

View File

@ -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;

View File

@ -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)

View File

@ -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