Use F:n for feature Ids instead of Fn:m as discussed in #1912

Update Demod Analzyer to use AvailableChannelsOrFeature - removes need for Refresh Channels button
This commit is contained in:
srcejon 2024-03-05 10:28:01 +00:00
parent 84e091a1b2
commit 885cddc981
12 changed files with 104 additions and 208 deletions

View File

@ -39,7 +39,6 @@
MESSAGE_CLASS_DEFINITION(DemodAnalyzer::MsgConfigureDemodAnalyzer, Message)
MESSAGE_CLASS_DEFINITION(DemodAnalyzer::MsgStartStop, Message)
MESSAGE_CLASS_DEFINITION(DemodAnalyzer::MsgRefreshChannels, Message)
MESSAGE_CLASS_DEFINITION(DemodAnalyzer::MsgReportChannels, Message)
MESSAGE_CLASS_DEFINITION(DemodAnalyzer::MsgSelectChannel, Message)
MESSAGE_CLASS_DEFINITION(DemodAnalyzer::MsgReportSampleRate, Message)
@ -52,6 +51,7 @@ DemodAnalyzer::DemodAnalyzer(WebAPIAdapterInterface *webAPIAdapterInterface) :
m_thread(nullptr),
m_running(false),
m_worker(nullptr),
m_availableChannelOrFeatureHandler(DemodAnalyzerSettings::m_channelURIs),
m_spectrumVis(SDR_RX_SCALEF),
m_selectedChannel(nullptr),
m_dataPipe(nullptr)
@ -67,10 +67,23 @@ DemodAnalyzer::DemodAnalyzer(WebAPIAdapterInterface *webAPIAdapterInterface) :
this,
&DemodAnalyzer::networkManagerFinished
);
QObject::connect(
&m_availableChannelOrFeatureHandler,
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
this,
&DemodAnalyzer::channelsOrFeaturesChanged
);
m_availableChannelOrFeatureHandler.scanAvailableChannelsAndFeatures();
}
DemodAnalyzer::~DemodAnalyzer()
{
QObject::disconnect(
&m_availableChannelOrFeatureHandler,
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
this,
&DemodAnalyzer::channelsOrFeaturesChanged
);
QObject::disconnect(
m_networkManager,
&QNetworkAccessManager::finished,
@ -193,12 +206,6 @@ bool DemodAnalyzer::handleMessage(const Message& cmd)
return true;
}
else if (MsgRefreshChannels::match(cmd))
{
qDebug() << "DemodAnalyzer::handleMessage: MsgRefreshChannels";
updateChannels();
return true;
}
else if (MsgSelectChannel::match(cmd))
{
MsgSelectChannel& cfg = (MsgSelectChannel&) cmd;
@ -304,60 +311,25 @@ void DemodAnalyzer::applySettings(const DemodAnalyzerSettings& settings, const Q
}
}
void DemodAnalyzer::updateChannels()
void DemodAnalyzer::channelsOrFeaturesChanged(const QStringList& renameFrom, const QStringList& renameTo)
{
MainCore *mainCore = MainCore::instance();
std::vector<DeviceSet*>& deviceSets = mainCore->getDeviceSets();
std::vector<DeviceSet*>::const_iterator it = deviceSets.begin();
m_availableChannels.clear();
int deviceIndex = 0;
for (; it != deviceSets.end(); ++it, deviceIndex++)
{
DSPDeviceSourceEngine *deviceSourceEngine = (*it)->m_deviceSourceEngine;
DSPDeviceSinkEngine *deviceSinkEngine = (*it)->m_deviceSinkEngine;
if (deviceSourceEngine || deviceSinkEngine)
{
for (int chi = 0; chi < (*it)->getNumberOfChannels(); chi++)
{
ChannelAPI *channel = (*it)->getChannelAt(chi);
int i = DemodAnalyzerSettings::m_channelURIs.indexOf(channel->getURI());
if (i >= 0)
{
DemodAnalyzerSettings::AvailableChannel availableChannel =
DemodAnalyzerSettings::AvailableChannel{
deviceSinkEngine != nullptr,
deviceIndex,
chi,
channel,
DemodAnalyzerSettings::m_channelTypes.at(i)
};
m_availableChannels[channel] = availableChannel;
}
}
}
}
m_availableChannels = m_availableChannelOrFeatureHandler.getAvailableChannelOrFeatureList();
notifyUpdate(renameFrom, renameTo);
}
void DemodAnalyzer::notifyUpdate(const QStringList& renameFrom, const QStringList& renameTo)
{
if (getMessageQueueToGUI())
{
MsgReportChannels *msgToGUI = MsgReportChannels::create();
QList<DemodAnalyzerSettings::AvailableChannel>& msgAvailableChannels = msgToGUI->getAvailableChannels();
QHash<ChannelAPI*, DemodAnalyzerSettings::AvailableChannel>::iterator it = m_availableChannels.begin();
for (; it != m_availableChannels.end(); ++it) {
msgAvailableChannels.push_back(*it);
}
getMessageQueueToGUI()->push(msgToGUI);
MsgReportChannels *msg = MsgReportChannels::create(renameFrom, renameTo);
msg->getAvailableChannels() = m_availableChannels;
getMessageQueueToGUI()->push(msg);
}
}
void DemodAnalyzer::setChannel(ChannelAPI *selectedChannel)
{
if ((selectedChannel == m_selectedChannel) || !m_availableChannels.contains(selectedChannel)) {
if ((selectedChannel == m_selectedChannel) || (m_availableChannels.indexOfObject(selectedChannel) == -1)) {
return;
}
@ -691,21 +663,7 @@ void DemodAnalyzer::handleDataPipeToBeDeleted(int reason, QObject *object)
m_worker->getInputMessageQueue()->push(msg);
}
m_availableChannels.remove((ChannelAPI*) object);
m_selectedChannel = nullptr;
if (getMessageQueueToGUI())
{
MsgReportChannels *msgToGUI = MsgReportChannels::create();
QList<DemodAnalyzerSettings::AvailableChannel>& msgAvailableChannels = msgToGUI->getAvailableChannels();
QHash<ChannelAPI*, DemodAnalyzerSettings::AvailableChannel>::iterator it = m_availableChannels.begin();
for (; it != m_availableChannels.end(); ++it) {
msgAvailableChannels.push_back(*it);
}
getMessageQueueToGUI()->push(msgToGUI);
}
}
}
@ -730,12 +688,7 @@ int DemodAnalyzer::webapiActionsPost(
return 404;
}
MsgRefreshChannels *m1 = MsgRefreshChannels::create();
getInputMessageQueue()->push(m1);
MsgSelectChannel *msg = MsgSelectChannel::create(chan);
getInputMessageQueue()->push(msg);
return 200;
}

View File

@ -27,6 +27,7 @@
#include "util/message.h"
#include "dsp/spectrumvis.h"
#include "dsp/scopevis.h"
#include "availablechannelorfeaturehandler.h"
#include "demodanalyzersettings.h"
@ -89,35 +90,27 @@ public:
{ }
};
class MsgRefreshChannels : public Message {
MESSAGE_CLASS_DECLARATION
public:
static MsgRefreshChannels* create() {
return new MsgRefreshChannels();
}
protected:
MsgRefreshChannels() :
Message()
{ }
};
class MsgReportChannels : public Message {
MESSAGE_CLASS_DECLARATION
public:
QList<DemodAnalyzerSettings::AvailableChannel>& getAvailableChannels() { return m_availableChannels; }
AvailableChannelOrFeatureList& getAvailableChannels() { return m_availableChannels; }
const QStringList& getRenameFrom() const { return m_renameFrom; }
const QStringList& getRenameTo() const { return m_renameTo; }
static MsgReportChannels* create() {
return new MsgReportChannels();
static MsgReportChannels* create(const QStringList& renameFrom, const QStringList& renameTo) {
return new MsgReportChannels(renameFrom, renameTo);
}
private:
QList<DemodAnalyzerSettings::AvailableChannel> m_availableChannels;
AvailableChannelOrFeatureList m_availableChannels;
QStringList m_renameFrom;
QStringList m_renameTo;
MsgReportChannels() :
Message()
MsgReportChannels(const QStringList& renameFrom, const QStringList& renameTo) :
Message(),
m_renameFrom(renameFrom),
m_renameTo(renameTo)
{}
};
@ -212,7 +205,8 @@ private:
DemodAnalyzerSettings m_settings;
SpectrumVis m_spectrumVis;
ScopeVis m_scopeVis;
QHash<ChannelAPI*, DemodAnalyzerSettings::AvailableChannel> m_availableChannels;
AvailableChannelOrFeatureList m_availableChannels;
AvailableChannelOrFeatureHandler m_availableChannelOrFeatureHandler;
ChannelAPI *m_selectedChannel;
ObjectPipe *m_dataPipe;
int m_sampleRate;
@ -223,13 +217,14 @@ private:
void start();
void stop();
void applySettings(const DemodAnalyzerSettings& settings, const QList<QString>& settingsKeys, bool force = false);
void updateChannels();
void notifyUpdate(const QStringList& renameFrom, const QStringList& renameTo);
void setChannel(ChannelAPI *selectedChannel);
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const DemodAnalyzerSettings& settings, bool force);
private slots:
void networkManagerFinished(QNetworkReply *reply);
void handleChannelMessageQueue(MessageQueue *messageQueues);
void channelsOrFeaturesChanged(const QStringList& renameFrom, const QStringList& renameTo);
void handleDataPipeToBeDeleted(int reason, QObject *object);
};

View File

@ -238,19 +238,14 @@ void DemodAnalyzerGUI::updateChannelList()
ui->channels->blockSignals(true);
ui->channels->clear();
QList<DemodAnalyzerSettings::AvailableChannel>::const_iterator it = m_availableChannels.begin();
AvailableChannelOrFeatureList::const_iterator it = m_availableChannels.begin();
int selectedItem = -1;
for (int i = 0; it != m_availableChannels.end(); ++it, i++)
{
ui->channels->addItem(tr("%1%2:%3 %4")
.arg(it->m_tx ? "T" : "R")
.arg(it->m_deviceSetIndex)
.arg(it->m_channelIndex)
.arg(it->m_id)
);
ui->channels->addItem(it->getLongId());
if (it->m_channelAPI == m_selectedChannel) {
if (it->m_object == m_selectedChannel) {
selectedItem = i;
}
}
@ -317,17 +312,11 @@ void DemodAnalyzerGUI::on_startStop_toggled(bool checked)
}
}
void DemodAnalyzerGUI::on_devicesRefresh_clicked()
{
DemodAnalyzer::MsgRefreshChannels *msg = DemodAnalyzer::MsgRefreshChannels::create();
m_demodAnalyzer->getInputMessageQueue()->push(msg);
}
void DemodAnalyzerGUI::on_channels_currentIndexChanged(int index)
{
if ((index >= 0) && (index < m_availableChannels.size()))
{
m_selectedChannel = m_availableChannels[index].m_channelAPI;
m_selectedChannel = qobject_cast<ChannelAPI*>(m_availableChannels[index].m_object);
DemodAnalyzer::MsgSelectChannel *msg = DemodAnalyzer::MsgSelectChannel::create(m_selectedChannel);
m_demodAnalyzer->getInputMessageQueue()->push(msg);
}
@ -448,7 +437,6 @@ void DemodAnalyzerGUI::applySettings(bool force)
void DemodAnalyzerGUI::makeUIConnections()
{
QObject::connect(ui->startStop, &ButtonSwitch::toggled, this, &DemodAnalyzerGUI::on_startStop_toggled);
QObject::connect(ui->devicesRefresh, &QPushButton::clicked, this, &DemodAnalyzerGUI::on_devicesRefresh_clicked);
QObject::connect(ui->channels, qOverload<int>(&QComboBox::currentIndexChanged), this, &DemodAnalyzerGUI::on_channels_currentIndexChanged);
QObject::connect(ui->channelApply, &QPushButton::clicked, this, &DemodAnalyzerGUI::on_channelApply_clicked);
QObject::connect(ui->log2Decim, qOverload<int>(&QComboBox::currentIndexChanged), this, &DemodAnalyzerGUI::on_log2Decim_currentIndexChanged);

View File

@ -25,6 +25,7 @@
#include "feature/featuregui.h"
#include "util/movingaverage.h"
#include "util/messagequeue.h"
#include "availablechannelorfeaturehandler.h"
#include "settings/rollupstate.h"
#include "demodanalyzersettings.h"
@ -71,7 +72,7 @@ private:
MessageQueue m_inputMessageQueue;
QTimer m_statusTimer;
int m_lastFeatureState;
QList<DemodAnalyzerSettings::AvailableChannel> m_availableChannels;
AvailableChannelOrFeatureList m_availableChannels;
ChannelAPI *m_selectedChannel;
MovingAverageUtil<double, double, 40> m_channelPowerAvg;
@ -91,7 +92,6 @@ private slots:
void onWidgetRolled(QWidget* widget, bool rollDown);
void handleInputMessages();
void on_startStop_toggled(bool checked);
void on_devicesRefresh_clicked();
void on_channels_currentIndexChanged(int index);
void on_channelApply_clicked();
void on_log2Decim_currentIndexChanged(int index);

View File

@ -91,26 +91,6 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="devicesRefresh">
<property name="maximumSize">
<size>
<width>24</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Refresh indexes of available device sets</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/recycle.png</normaloff>:/recycle.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="channelsLabel">
<property name="text">
@ -511,18 +491,6 @@
<header>gui/rollupcontents.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GLSpectrum</class>
<extends>QWidget</extends>
<header>gui/glspectrum.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GLSpectrumGUI</class>
<extends>QWidget</extends>
<header>gui/glspectrumgui.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GLScope</class>
<extends>QWidget</extends>
@ -535,6 +503,18 @@
<header>gui/glscopegui.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GLSpectrum</class>
<extends>QWidget</extends>
<header>gui/glspectrum.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GLSpectrumGUI</class>
<extends>QWidget</extends>
<header>gui/glspectrumgui.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../../sdrgui/resources/res.qrc"/>

View File

@ -25,31 +25,6 @@
#include "demodanalyzersettings.h"
const QStringList DemodAnalyzerSettings::m_channelTypes = {
QStringLiteral("AISDemod"),
QStringLiteral("AISMod"),
QStringLiteral("AMDemod"),
QStringLiteral("AMMod"),
QStringLiteral("BFMDemod"),
QStringLiteral("DABDemod"),
QStringLiteral("DSDDemod"),
QStringLiteral("EndOfTrainDemod"),
QStringLiteral("FT8Demod"),
QStringLiteral("M17Demod"),
QStringLiteral("M17Mmod"),
QStringLiteral("NFMDemod"),
QStringLiteral("NFMMod"),
QStringLiteral("PacketDemod"),
QStringLiteral("PacketMod"),
QStringLiteral("RadiosondeDemod"),
QStringLiteral("PSK31Mod"),
QStringLiteral("RTTYMod"),
QStringLiteral("SSBDemod"),
QStringLiteral("SSBMod"),
QStringLiteral("WFMDemod"),
QStringLiteral("WFMMod"),
};
const QStringList DemodAnalyzerSettings::m_channelURIs = {
QStringLiteral("sdrangel.channel.aisdemod"),
QStringLiteral("sdrangel.channel.modais"),

View File

@ -31,19 +31,6 @@ class ChannelAPI;
struct DemodAnalyzerSettings
{
struct AvailableChannel
{
bool m_tx;
int m_deviceSetIndex;
int m_channelIndex;
ChannelAPI *m_channelAPI;
QString m_id;
AvailableChannel() = default;
AvailableChannel(const AvailableChannel&) = default;
AvailableChannel& operator=(const AvailableChannel&) = default;
};
int m_log2Decim;
QString m_title;
quint32 m_rgbColor;
@ -71,7 +58,6 @@ struct DemodAnalyzerSettings
void applySettings(const QStringList& settingsKeys, const DemodAnalyzerSettings& settings);
QString getDebugString(const QStringList& settingsKeys, bool force=false) const;
static const QStringList m_channelTypes;
static const QStringList m_channelURIs;
};

View File

@ -8,10 +8,15 @@ Rx plugins are:
- AIS demodulator
- AM demodulator
- Broadcast FM demodulator
- DAB demodulator
- DSD (FM digital voice) demodulator
- End-of-train demodulator
- FT8 demodulator
- M17 demodulator
- NFM demodulator
- Packet demodulator
- Radiosonde demodulator
- SSB demodulator
- WFM demodulator
@ -19,8 +24,11 @@ Tx plugins are:
- AIS modulator
- AM modulator
- M17 modulator
- NFM modulator
- Packet modulator
- PSK31 modulator
- RTTY modulator
- SSB modulator
- WFM modulator
@ -41,18 +49,13 @@ The interface is essentially divided in the following sections
Typical sequence of operations:
1. Start the plugin (A.1)
2. Scan for displayable channels (A.2)
3. Select channel (A.3)
4. If channel is unique or default selection has not been changed press the (re)apply button (A.4)
2. Select channel (A.3)
3. If channel is unique or default selection has not been changed press the (re)apply button (A.4)
<h3>A.1: Start/Stop plugin</h3>
This button starts or stops the plugin
<h3>A.2: (Re)scan available channels</h3>
Use this button to scan for channels available for display (see list of channel types in introduction)
<h3>A.3: Channel selection</h3>
Use this combo to select which channel to use for display. Channel is selected upon change. If channel is not changed or there is only one in the list you have to use the (re)apply button (A.4) to effectively connect the channel to the analyzer.

View File

@ -955,7 +955,7 @@ void SatelliteTrackerGUI::plotPolarChart()
if (m_settings.m_drawRotators != SatelliteTrackerSettings::NO_ROTATORS)
{
// Plot rotator position
QString ourSourceName = QString("F0:%1 %2").arg(m_satelliteTracker->getIndexInFeatureSet()).arg(m_satelliteTracker->getIdentifier()); // Only one feature set in practice?
QString ourSourceName = QString("F:%1 %2").arg(m_satelliteTracker->getIndexInFeatureSet()).arg(m_satelliteTracker->getIdentifier());
std::vector<FeatureSet*>& featureSets = MainCore::instance()->getFeatureeSets();
for (int featureSetIndex = 0; featureSetIndex < (int)featureSets.size(); featureSetIndex++)
{

View File

@ -1943,7 +1943,7 @@ void StarTrackerGUI::plotElevationPolarChart()
{
int redrawTime = 0;
// Plot rotator position
QString ourSourceName = QString("F0:%1 %2").arg(m_starTracker->getIndexInFeatureSet()).arg(m_starTracker->getIdentifier()); // Only one feature set in practice?
QString ourSourceName = QString("F:%1 %2").arg(m_starTracker->getIndexInFeatureSet()).arg(m_starTracker->getIdentifier());
std::vector<FeatureSet*>& featureSets = MainCore::instance()->getFeatureeSets();
for (int featureSetIndex = 0; featureSetIndex < (int)featureSets.size(); featureSetIndex++)
{

View File

@ -20,6 +20,31 @@
#include "channel/channelapi.h"
#include "maincore.h"
bool AvailableChannelOrFeature::operator==(const AvailableChannelOrFeature& a) const
{
return (m_kind == a.m_kind) && (m_superIndex == a.m_superIndex) && (m_index == a.m_index) && (m_type == a.m_type) && ((m_kind == 'M') && (m_streamIndex == a.m_streamIndex));
}
QString AvailableChannelOrFeature::getId() const
{
QString id;
if (m_kind == 'F') {
id = QString("%1:%2").arg(m_kind).arg(m_index); // superIndex always 0 for features
} else {
id = QString("%1%2:%3").arg(m_kind).arg(m_superIndex).arg(m_index);
}
if (m_kind == 'M') {
id.append(QString(".%1").arg(m_streamIndex));
}
return id;
}
QString AvailableChannelOrFeature::getLongId() const
{
return QString("%1 %2").arg(getId()).arg(m_type);
}
int AvailableChannelOrFeatureList::indexOfObject(const QObject *object, int from) const
{
for (int index = from; index < size(); index++)

View File

@ -18,10 +18,13 @@
#ifndef SDRBASE_AVAILABLECHANNELORFEATURE_H_
#define SDRBASE_AVAILABLECHANNELORFEATURE_H_
#include "pipes/messagepipes.h"
#include <QString>
#include <QObject>
//#include "pipes/messagepipes.h"
#include "export.h"
struct AvailableChannelOrFeature
struct SDRBASE_API AvailableChannelOrFeature
{
QChar m_kind; //!< 'R' or 'T' for channel, 'M' for MIMO channel, 'F' for feature as from MainCore::getDeviceSetTypeId
int m_superIndex; //!< Device Set index or Feature Set index
@ -34,21 +37,9 @@ struct AvailableChannelOrFeature
AvailableChannelOrFeature(const AvailableChannelOrFeature&) = default;
AvailableChannelOrFeature& operator=(const AvailableChannelOrFeature&) = default;
bool operator==(const AvailableChannelOrFeature& a) const {
return (m_kind == a.m_kind) && (m_superIndex == a.m_superIndex) && (m_index == a.m_index) && (m_type == a.m_type) && ((m_kind == 'M') && (m_streamIndex == a.m_streamIndex));
}
QString getId() const { // Eg: "R3:4"
QString id = QString("%1%2:%3").arg(m_kind).arg(m_superIndex).arg(m_index);
if (m_kind == 'M') {
id.append(QString(".%1").arg(m_streamIndex));
}
return id;
}
QString getLongId() const { // Eg: "F0:1 StarTracker"
return QString("%1 %2").arg(getId()).arg(m_type);
}
bool operator==(const AvailableChannelOrFeature& a) const;
QString getId() const; //!< Eg: "R3:4"
QString getLongId() const; //!< Eg: "F:1 StarTracker"
};
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)