1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-21 23:55:13 -05:00

Compare commits

...

15 Commits

Author SHA1 Message Date
Edouard Griffiths
42cabeb96d
Merge 36349e2837 into 6b2573d955 2024-08-24 11:17:43 +00:00
f4exb
36349e2837 Sonar fixes 2024-08-24 13:17:02 +02:00
f4exb
3a7de65ee5 All device plugins: make sure start and stop are effective once only. PArt of #2159 2024-08-21 05:27:01 +02:00
f4exb
38043ebdbc BladeRF2Output: removed applySettings from stop method 2024-08-19 00:42:57 +02:00
f4exb
49074d1ce9 DeviceSet and DeviceUISet: use delete channel API instead of destroy method so that the virtual destructor of the channel is called appropriately 2024-08-19 00:31:55 +02:00
f4exb
24dba6f7f1 Fixed threading model for DSPDeviceSinkEngine plus other fixes. Part of #2159 2024-08-18 13:37:27 +02:00
f4exb
0208d11376 SSBMod: revised thread processing 2024-08-18 13:36:30 +02:00
f4exb
7d1af5b24f Removed SyncMessenger from DSPDeviceSinkEngine. Part of #2159 2024-08-17 22:34:30 +02:00
f4exb
7739dfd468 AMMod: revised thread processing 2024-08-17 22:33:55 +02:00
f4exb
4a2032a26a NFMMod: revised thread processing 2024-08-17 22:33:30 +02:00
f4exb
436d1665ea Fixed threading model for DSPDeviceMIMOEngine plus other fixes. Part of #2159 2024-08-17 11:24:19 +02:00
f4exb
f5e7708612 RTLSDR: make sure start and stop are effective once only. PArt of #2159 2024-08-17 11:22:09 +02:00
f4exb
0ff75e1538 Removed SyncMessenger from DSPDeviceMIMOEngine. Part of #2159 2024-08-15 03:08:28 +02:00
f4exb
580fbda09c Fixed threading model for DSPDeviceSourceEngine. Part of #2159 2024-08-14 22:08:49 +02:00
f4exb
4a6943b4d9 Removed SyncMessenger from DSPDeviceSourceEngine. Part of #2159 2024-08-14 17:24:21 +02:00
87 changed files with 3186 additions and 3094 deletions

View File

@ -59,6 +59,7 @@ void WDSPRxBaseband::reset()
{
QMutexLocker mutexLocker(&m_mutex);
m_sink.applyAudioSampleRate(DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate());
mutexLocker.unlock();
m_sampleFifo.reset();
m_channelSampleRate = 0;
}

View File

@ -49,7 +49,7 @@
WDSPRxGUI* WDSPRxGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel)
{
WDSPRxGUI* gui = new WDSPRxGUI(pluginAPI, deviceUISet, rxChannel);
auto* gui = new WDSPRxGUI(pluginAPI, deviceUISet, rxChannel);
return gui;
}
@ -98,7 +98,7 @@ bool WDSPRxGUI::handleMessage(const Message& message)
if (WDSPRx::MsgConfigureWDSPRx::match(message))
{
qDebug("WDSPRxGUI::handleMessage: WDSPRx::MsgConfigureWDSPRx");
const WDSPRx::MsgConfigureWDSPRx& cfg = (WDSPRx::MsgConfigureWDSPRx&) message;
auto& cfg = (const WDSPRx::MsgConfigureWDSPRx&) message;
m_settings = cfg.getSettings();
blockApplySettings(true);
ui->spectrumGUI->updateSettings();
@ -118,7 +118,7 @@ bool WDSPRxGUI::handleMessage(const Message& message)
}
else if (DSPSignalNotification::match(message))
{
const DSPSignalNotification& notif = (const DSPSignalNotification&) message;
auto& notif = (const DSPSignalNotification&) message;
m_deviceCenterFrequency = notif.getCenterFrequency();
m_basebandSampleRate = notif.getSampleRate();
qDebug("WDSPRxGUI::handleMessage: DSPSignalNotification: centerFrequency: %lld sampleRate: %d",
@ -138,7 +138,7 @@ void WDSPRxGUI::handleInputMessages()
{
Message* message;
while ((message = getInputMessageQueue()->pop()) != 0)
while ((message = getInputMessageQueue()->pop()) != nullptr)
{
if (handleMessage(*message))
{
@ -183,7 +183,7 @@ void WDSPRxGUI::on_dsb_toggled(bool dsb)
void WDSPRxGUI::on_deltaFrequency_changed(qint64 value)
{
m_channelMarker.setCenterFrequency(value);
m_channelMarker.setCenterFrequency((int) value);
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
updateAbsoluteCenterFrequency();
applySettings();
@ -205,7 +205,7 @@ void WDSPRxGUI::on_lowCut_valueChanged(int value)
void WDSPRxGUI::on_volume_valueChanged(int value)
{
ui->volumeText->setText(QString("%1").arg(value));
m_settings.m_volume = CalcDb::powerFromdB(value);
m_settings.m_volume = (Real) CalcDb::powerFromdB(value);
applySettings();
}
@ -279,7 +279,7 @@ void WDSPRxGUI::on_rit_toggled(bool checked)
{
m_settings.m_rit = checked;
m_settings.m_profiles[m_settings.m_profileIndex].m_rit = m_settings.m_rit;
m_channelMarker.setShift(checked ? m_settings.m_ritFrequency: 0);
m_channelMarker.setShift(checked ? (int) m_settings.m_ritFrequency: 0);
applySettings();
}
@ -406,7 +406,7 @@ void WDSPRxGUI::on_profileIndex_valueChanged(int value)
void WDSPRxGUI::on_demod_currentIndexChanged(int index)
{
WDSPRxProfile::WDSPRxDemod demod = (WDSPRxProfile::WDSPRxDemod) index;
auto demod = (WDSPRxProfile::WDSPRxDemod) index;
if ((m_settings.m_demod != WDSPRxProfile::DemodSSB) && (demod == WDSPRxProfile::DemodSSB)) {
m_settings.m_dsb = false;
@ -480,7 +480,7 @@ void WDSPRxGUI::onMenuDialogCalled(const QPoint &p)
resetContextMenuType();
}
void WDSPRxGUI::onWidgetRolled(QWidget* widget, bool rollDown)
void WDSPRxGUI::onWidgetRolled(const QWidget* widget, bool rollDown)
{
(void) widget;
(void) rollDown;
@ -524,7 +524,7 @@ WDSPRxGUI::WDSPRxGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam
m_wdspRx = (WDSPRx*) rxChannel;
m_spectrumVis = m_wdspRx->getSpectrumVis();
m_spectrumVis->setGLSpectrum(ui->glSpectrum);
m_wdspRx->setMessageQueueToGUI(getInputMessageQueue());
m_wdspRx->setMessageQueueToGUI(WDSPRxGUI::getInputMessageQueue());
m_audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute);
connect(m_audioMuteRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioSelect(const QPoint &)));
@ -588,7 +588,7 @@ WDSPRxGUI::WDSPRxGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam
m_deviceUISet->addChannelMarker(&m_channelMarker);
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
connect(WDSPRxGUI::getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
m_iconDSBUSB.addPixmap(QPixmap("://dsb.png"), QIcon::Normal, QIcon::On);
@ -654,7 +654,7 @@ uint32_t WDSPRxGUI::getValidAudioSampleRate() const
return sr;
}
unsigned int WDSPRxGUI::spanLog2Max()
unsigned int WDSPRxGUI::spanLog2Max() const
{
unsigned int spanLog2 = 0;
for (; getValidAudioSampleRate() / (1<<spanLog2) >= 1000; spanLog2++);
@ -668,7 +668,6 @@ void WDSPRxGUI::applyBandwidths(unsigned int spanLog2, bool force)
unsigned int limit = s2max < 1 ? 0 : s2max - 1;
ui->spanLog2->setMaximum(limit);
bool dsb = ui->dsb->isChecked();
//int spanLog2 = ui->spanLog2->value();
m_spectrumRate = getValidAudioSampleRate() / (1<<spanLog2);
int bw = ui->BW->value();
int lw = ui->lowCut->value();
@ -764,8 +763,8 @@ void WDSPRxGUI::applyBandwidths(unsigned int spanLog2, bool force)
m_settings.m_dsb = dsb;
m_settings.m_profiles[m_settings.m_profileIndex].m_dsb = dsb;
m_settings.m_profiles[m_settings.m_profileIndex].m_spanLog2 = spanLog2;
m_settings.m_profiles[m_settings.m_profileIndex].m_highCutoff = bw * 100;
m_settings.m_profiles[m_settings.m_profileIndex].m_lowCutoff = lw * 100;
m_settings.m_profiles[m_settings.m_profileIndex].m_highCutoff = (Real) (bw * 100);
m_settings.m_profiles[m_settings.m_profileIndex].m_lowCutoff = (Real) (lw * 100);
applySettings(force);
@ -785,11 +784,11 @@ void WDSPRxGUI::displaySettings()
{
m_channelMarker.blockSignals(true);
m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
m_channelMarker.setBandwidth(m_settings.m_profiles[m_settings.m_profileIndex].m_highCutoff * 2);
m_channelMarker.setBandwidth((int) (m_settings.m_profiles[m_settings.m_profileIndex].m_highCutoff * 2));
m_channelMarker.setTitle(m_settings.m_title);
m_channelMarker.setLowCutoff(m_settings.m_profiles[m_settings.m_profileIndex].m_lowCutoff);
m_channelMarker.setLowCutoff((int) m_settings.m_profiles[m_settings.m_profileIndex].m_lowCutoff);
int shift = m_settings.m_profiles[m_settings.m_profileIndex].m_rit ?
m_settings.m_profiles[m_settings.m_profileIndex].m_ritFrequency :
(int) m_settings.m_profiles[m_settings.m_profileIndex].m_ritFrequency :
0;
m_channelMarker.setShift(shift);
@ -880,7 +879,7 @@ void WDSPRxGUI::displaySettings()
ui->dsb->setChecked(m_settings.m_dsb);
ui->spanLog2->setValue(1 + ui->spanLog2->maximum() - m_settings.m_profiles[m_settings.m_profileIndex].m_spanLog2);
ui->BW->setValue(m_settings.m_profiles[m_settings.m_profileIndex].m_highCutoff / 100.0);
ui->BW->setValue((int) (m_settings.m_profiles[m_settings.m_profileIndex].m_highCutoff / 100.0));
s = QString::number(m_settings.m_profiles[m_settings.m_profileIndex].m_highCutoff/1000.0, 'f', 1);
if (m_settings.m_dsb) {
@ -899,10 +898,10 @@ void WDSPRxGUI::displaySettings()
// The only one of the four signals triggering applyBandwidths will trigger it once only with all other values
// set correctly and therefore validate the settings and apply them to dependent widgets
ui->lowCut->setValue(m_settings.m_profiles[m_settings.m_profileIndex].m_lowCutoff / 100.0);
ui->lowCut->setValue((int) (m_settings.m_profiles[m_settings.m_profileIndex].m_lowCutoff / 100.0));
ui->lowCutText->setText(tr("%1k").arg(m_settings.m_profiles[m_settings.m_profileIndex].m_lowCutoff / 1000.0));
int volume = CalcDb::dbPower(m_settings.m_volume);
auto volume = (int) CalcDb::dbPower(m_settings.m_volume);
ui->volume->setValue(volume);
ui->volumeText->setText(QString("%1").arg(volume));
@ -1199,15 +1198,11 @@ void WDSPRxGUI::amSetup(int iValueChanged)
auto valueChanged = (WDSPRxAMDialog::ValueChanged) iValueChanged;
switch (valueChanged)
if (valueChanged == WDSPRxAMDialog::ChangedFadeLevel)
{
case WDSPRxAMDialog::ChangedFadeLevel:
m_settings.m_amFadeLevel = m_amDialog->getFadeLevel();
m_settings.m_profiles[m_settings.m_profileIndex].m_amFadeLevel = m_settings.m_amFadeLevel;
applySettings();
break;
default:
break;
}
}
@ -1369,21 +1364,18 @@ void WDSPRxGUI::panSetup(int iValueChanged)
auto valueChanged = (WDSPRxPanDialog::ValueChanged) iValueChanged;
switch (valueChanged)
if (valueChanged == WDSPRxPanDialog::ChangedPan)
{
case WDSPRxPanDialog::ChangedPan:
m_settings.m_audioPan = m_panDialog->getPan();
m_settings.m_profiles[m_settings.m_profileIndex].m_audioPan = m_settings.m_audioPan;
applySettings();
break;
default:
break;
}
}
void WDSPRxGUI::tick()
{
double powDbAvg, powDbPeak;
double powDbAvg;
double powDbPeak;
int nbMagsqSamples;
m_wdspRx->getMagSqLevels(powDbAvg, powDbPeak, nbMagsqSamples); // powers directly in dB
@ -1416,7 +1408,7 @@ void WDSPRxGUI::tick()
m_tickCount++;
}
void WDSPRxGUI::makeUIConnections()
void WDSPRxGUI::makeUIConnections() const
{
QObject::connect(ui->deltaFrequency, &ValueDialZ::changed, this, &WDSPRxGUI::on_deltaFrequency_changed);
QObject::connect(ui->audioBinaural, &QToolButton::toggled, this, &WDSPRxGUI::on_audioBinaural_toggled);

View File

@ -58,21 +58,21 @@ public:
static WDSPRxGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel);
virtual void destroy();
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; };
virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; };
virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; };
virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; };
virtual QString getTitle() const { return m_settings.m_title; };
virtual QColor getTitleColor() const { return m_settings.m_rgbColor; };
virtual void zetHidden(bool hidden) { m_settings.m_hidden = hidden; }
virtual bool getHidden() const { return m_settings.m_hidden; }
virtual ChannelMarker& getChannelMarker() { return m_channelMarker; }
virtual int getStreamIndex() const { return m_settings.m_streamIndex; }
virtual void setStreamIndex(int streamIndex) { m_settings.m_streamIndex = streamIndex; }
void resetToDefaults() final;
QByteArray serialize() const final;
bool deserialize(const QByteArray& data) final;
MessageQueue *getInputMessageQueue() final { return &m_inputMessageQueue; }
void setWorkspaceIndex(int index) final { m_settings.m_workspaceIndex = index; };
int getWorkspaceIndex() const final { return m_settings.m_workspaceIndex; };
void setGeometryBytes(const QByteArray& blob) final { m_settings.m_geometryBytes = blob; };
QByteArray getGeometryBytes() const final { return m_settings.m_geometryBytes; };
QString getTitle() const final { return m_settings.m_title; };
QColor getTitleColor() const final { return m_settings.m_rgbColor; };
void zetHidden(bool hidden) final { m_settings.m_hidden = hidden; }
bool getHidden() const final { return m_settings.m_hidden; }
ChannelMarker& getChannelMarker() final { return m_channelMarker; }
int getStreamIndex() const final { return m_settings.m_streamIndex; }
void setStreamIndex(int streamIndex) final { m_settings.m_streamIndex = streamIndex; }
public slots:
void channelMarkerChangedByCursor();
@ -122,21 +122,21 @@ private:
QIcon m_iconDSBUSB;
QIcon m_iconDSBLSB;
explicit WDSPRxGUI(PluginAPI* pluginAPI, DeviceUISet* deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
virtual ~WDSPRxGUI();
explicit WDSPRxGUI(PluginAPI* pluginAPI, DeviceUISet* deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = nullptr);
~WDSPRxGUI() final;
bool blockApplySettings(bool block);
void applySettings(bool force = false);
void applyBandwidths(unsigned int spanLog2, bool force = false);
unsigned int spanLog2Max();
unsigned int spanLog2Max() const;
void displaySettings();
bool handleMessage(const Message& message);
void makeUIConnections();
void makeUIConnections() const;
void updateAbsoluteCenterFrequency();
uint32_t getValidAudioSampleRate() const;
void leaveEvent(QEvent*);
void enterEvent(EnterEventType*);
void leaveEvent(QEvent*) final;
void enterEvent(EnterEventType*) final;
private slots:
void on_deltaFrequency_changed(qint64 value);
@ -164,7 +164,7 @@ private slots:
void on_rit_toggled(bool checked);
void on_ritFrequency_valueChanged(int value);
void on_dbOrS_toggled(bool checked);
void onWidgetRolled(QWidget* widget, bool rollDown);
void onWidgetRolled(const QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p);
void handleInputMessages();
void audioSelect(const QPoint& p);

View File

@ -55,19 +55,9 @@ const char* const AMMod::m_channelId ="AMMod";
AMMod::AMMod(DeviceAPI *deviceAPI) :
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSource),
m_deviceAPI(deviceAPI),
m_fileSize(0),
m_recordLength(0),
m_sampleRate(48000)
m_deviceAPI(deviceAPI)
{
setObjectName(m_channelId);
m_thread = new QThread(this);
m_basebandSource = new AMModBaseband();
m_basebandSource->setInputFileStream(&m_ifstream);
m_basebandSource->setChannel(this);
m_basebandSource->moveToThread(m_thread);
applySettings(m_settings, true);
m_deviceAPI->addChannelSource(this);
@ -93,8 +83,8 @@ AMMod::~AMMod()
delete m_networkManager;
m_deviceAPI->removeChannelSourceAPI(this);
m_deviceAPI->removeChannelSource(this);
delete m_basebandSource;
delete m_thread;
AMMod::stop();
}
void AMMod::setDeviceAPI(DeviceAPI *deviceAPI)
@ -116,21 +106,61 @@ uint32_t AMMod::getNumberOfDeviceStreams() const
void AMMod::start()
{
if (m_running) {
return;
}
qDebug("AMMod::start");
m_thread = new QThread(this);
m_basebandSource = new AMModBaseband();
m_basebandSource->setInputFileStream(&m_ifstream);
m_basebandSource->setChannel(this);
m_basebandSource->reset();
m_basebandSource->setCWKeyer(&m_cwKeyer);
m_basebandSource->moveToThread(m_thread);
QObject::connect(
m_thread,
&QThread::finished,
m_basebandSource,
&QObject::deleteLater
);
QObject::connect(
m_thread,
&QThread::finished,
m_thread,
&QThread::deleteLater
);
m_thread->start();
AMModBaseband::MsgConfigureAMModBaseband *msg = AMModBaseband::MsgConfigureAMModBaseband::create(m_settings, true);
m_basebandSource->getInputMessageQueue()->push(msg);
if (m_levelMeter) {
connect(m_basebandSource, SIGNAL(levelChanged(qreal, qreal, int)), m_levelMeter, SLOT(levelChanged(qreal, qreal, int)));
}
m_running = true;
}
void AMMod::stop()
{
if (!m_running) {
return;
}
qDebug("AMMod::stop");
m_running = false;
m_thread->exit();
m_thread->wait();
}
void AMMod::pull(SampleVector::iterator& begin, unsigned int nbSamples)
{
if (m_running) {
m_basebandSource->pull(begin, nbSamples);
}
}
void AMMod::setCenterFrequency(qint64 frequency)
@ -150,7 +180,7 @@ bool AMMod::handleMessage(const Message& cmd)
{
if (MsgConfigureAMMod::match(cmd))
{
MsgConfigureAMMod& cfg = (MsgConfigureAMMod&) cmd;
auto& cfg = (const MsgConfigureAMMod&) cmd;
qDebug() << "AMMod::handleMessage: MsgConfigureAMMod";
applySettings(cfg.getSettings(), cfg.getForce());
@ -159,7 +189,7 @@ bool AMMod::handleMessage(const Message& cmd)
}
else if (MsgConfigureFileSourceName::match(cmd))
{
MsgConfigureFileSourceName& conf = (MsgConfigureFileSourceName&) cmd;
auto& conf = (const MsgConfigureFileSourceName&) cmd;
m_fileName = conf.getFileName();
qDebug() << "AMMod::handleMessage: MsgConfigureFileSourceName";
openFileStream();
@ -167,7 +197,7 @@ bool AMMod::handleMessage(const Message& cmd)
}
else if (MsgConfigureFileSourceSeek::match(cmd))
{
MsgConfigureFileSourceSeek& conf = (MsgConfigureFileSourceSeek&) cmd;
auto& conf = (const MsgConfigureFileSourceSeek&) cmd;
int seekPercentage = conf.getPercentage();
qDebug() << "AMMod::handleMessage: MsgConfigureFileSourceSeek";
seekFileStream(seekPercentage);
@ -192,7 +222,7 @@ bool AMMod::handleMessage(const Message& cmd)
}
else if (CWKeyer::MsgConfigureCWKeyer::match(cmd))
{
const CWKeyer::MsgConfigureCWKeyer& cfg = (CWKeyer::MsgConfigureCWKeyer&) cmd;
auto& cfg = (const CWKeyer::MsgConfigureCWKeyer&) cmd;
qDebug() << "AMMod::handleMessage: MsgConfigureCWKeyer";
if (m_settings.m_useReverseAPI) {
@ -203,11 +233,13 @@ bool AMMod::handleMessage(const Message& cmd)
}
else if (DSPSignalNotification::match(cmd))
{
// Forward to the source
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy
qDebug() << "AMMod::handleMessage: DSPSignalNotification";
m_basebandSource->getInputMessageQueue()->push(rep);
// Forward to the source
auto& notif = (const DSPSignalNotification&) cmd;
if (m_running) {
m_basebandSource->getInputMessageQueue()->push(new DSPSignalNotification(notif));
}
// Forward to GUI if any
if (getMessageQueueToGUI()) {
getMessageQueueToGUI()->push(new DSPSignalNotification(notif));
@ -239,7 +271,7 @@ void AMMod::openFileStream()
m_ifstream.seekg(0,std::ios_base::beg);
m_sampleRate = 48000; // fixed rate
m_recordLength = m_fileSize / (sizeof(Real) * m_sampleRate);
m_recordLength = (quint32) (m_fileSize / (sizeof(Real) * m_sampleRate));
qDebug() << "AMMod::openFileStream: " << m_fileName.toStdString().c_str()
<< " fileSize: " << m_fileSize << "bytes"
@ -338,8 +370,11 @@ void AMMod::applySettings(const AMModSettings& settings, bool force)
reverseAPIKeys.append("streamIndex");
}
if (m_running)
{
AMModBaseband::MsgConfigureAMModBaseband *msg = AMModBaseband::MsgConfigureAMModBaseband::create(settings, force);
m_basebandSource->getInputMessageQueue()->push(msg);
}
if (settings.m_useReverseAPI)
{
@ -354,7 +389,7 @@ void AMMod::applySettings(const AMModSettings& settings, bool force)
QList<ObjectPipe*> pipes;
MainCore::instance()->getMessagePipes().getMessagePipes(this, "settings", pipes);
if (pipes.size() > 0) {
if (!pipes.empty()) {
sendChannelSettings(pipes, reverseAPIKeys, settings, force);
}
@ -383,12 +418,12 @@ bool AMMod::deserialize(const QByteArray& data)
}
}
void AMMod::sendSampleRateToDemodAnalyzer()
void AMMod::sendSampleRateToDemodAnalyzer() const
{
QList<ObjectPipe*> pipes;
MainCore::instance()->getMessagePipes().getMessagePipes(this, "reportdemod", pipes);
if (pipes.size() > 0)
if (!pipes.empty())
{
for (const auto& pipe : pipes)
{
@ -412,7 +447,7 @@ int AMMod::webapiSettingsGet(
webapiFormatChannelSettings(response, m_settings);
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = response.getAmModSettings()->getCwKeyer();
const CWKeyerSettings& cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
const CWKeyerSettings& cwKeyerSettings = getCWKeyer()->getSettings();
CWKeyer::webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
return 200;
@ -440,11 +475,11 @@ int AMMod::webapiSettingsPutPatch(
if (channelSettingsKeys.contains("cwKeyer"))
{
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = response.getAmModSettings()->getCwKeyer();
CWKeyerSettings cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
CWKeyerSettings cwKeyerSettings = getCWKeyer()->getSettings();
CWKeyer::webapiSettingsPutPatch(channelSettingsKeys, cwKeyerSettings, apiCwKeyerSettings);
CWKeyer::MsgConfigureCWKeyer *msgCwKeyer = CWKeyer::MsgConfigureCWKeyer::create(cwKeyerSettings, force);
m_basebandSource->getCWKeyer().getInputMessageQueue()->push(msgCwKeyer);
getCWKeyer()->getInputMessageQueue()->push(msgCwKeyer);
if (m_guiMessageQueue) // forward to GUI if any
{
@ -515,13 +550,13 @@ void AMMod::webapiUpdateChannelSettings(
settings.m_reverseAPIAddress = *response.getAmModSettings()->getReverseApiAddress();
}
if (channelSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getAmModSettings()->getReverseApiPort();
settings.m_reverseAPIPort = (uint16_t) response.getAmModSettings()->getReverseApiPort();
}
if (channelSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getAmModSettings()->getReverseApiDeviceIndex();
settings.m_reverseAPIDeviceIndex = (uint16_t) response.getAmModSettings()->getReverseApiDeviceIndex();
}
if (channelSettingsKeys.contains("reverseAPIChannelIndex")) {
settings.m_reverseAPIChannelIndex = response.getAmModSettings()->getReverseApiChannelIndex();
settings.m_reverseAPIChannelIndex = (uint16_t) response.getAmModSettings()->getReverseApiChannelIndex();
}
if (settings.m_channelMarker && channelSettingsKeys.contains("channelMarker")) {
settings.m_channelMarker->updateFrom(channelSettingsKeys, response.getAmModSettings()->getChannelMarker());
@ -591,7 +626,7 @@ void AMMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respons
}
else
{
SWGSDRangel::SWGChannelMarker *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
auto *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
settings.m_channelMarker->formatTo(swgChannelMarker);
response.getAmModSettings()->setChannelMarker(swgChannelMarker);
}
@ -605,23 +640,27 @@ void AMMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respons
}
else
{
SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState();
auto *swgRollupState = new SWGSDRangel::SWGRollupState();
settings.m_rollupState->formatTo(swgRollupState);
response.getAmModSettings()->setRollupState(swgRollupState);
}
}
}
void AMMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
void AMMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) const
{
response.getAmModReport()->setChannelPowerDb(CalcDb::dbPower(getMagSq()));
response.getAmModReport()->setChannelPowerDb((float) CalcDb::dbPower(getMagSq()));
if (m_running)
{
response.getAmModReport()->setAudioSampleRate(m_basebandSource->getAudioSampleRate());
response.getAmModReport()->setChannelSampleRate(m_basebandSource->getChannelSampleRate());
}
}
void AMMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const AMModSettings& settings, bool force)
void AMMod::webapiReverseSendSettings(const QList<QString>& channelSettingsKeys, const AMModSettings& settings, bool force)
{
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
auto *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
webapiFormatChannelSettings(channelSettingsKeys, swgChannelSettings, settings, force);
QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
@ -632,8 +671,8 @@ void AMMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const
m_networkRequest.setUrl(QUrl(channelSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgChannelSettings->asJson().toUtf8());
buffer->seek(0);
@ -646,7 +685,7 @@ void AMMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const
void AMMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
{
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
auto *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
swgChannelSettings->setDirection(1); // single source (Tx)
swgChannelSettings->setChannelType(new QString("AMMod"));
swgChannelSettings->setAmModSettings(new SWGSDRangel::SWGAMModSettings());
@ -654,7 +693,7 @@ void AMMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
swgAMModSettings->setCwKeyer(new SWGSDRangel::SWGCWKeyerSettings());
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = swgAMModSettings->getCwKeyer();
m_basebandSource->getCWKeyer().webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
CWKeyer::webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
.arg(m_settings.m_reverseAPIAddress)
@ -664,8 +703,8 @@ void AMMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
m_networkRequest.setUrl(QUrl(channelSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgChannelSettings->asJson().toUtf8());
buffer->seek(0);
@ -678,7 +717,7 @@ void AMMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
void AMMod::sendChannelSettings(
const QList<ObjectPipe*>& pipes,
QList<QString>& channelSettingsKeys,
const QList<QString>& channelSettingsKeys,
const AMModSettings& settings,
bool force)
{
@ -688,7 +727,7 @@ void AMMod::sendChannelSettings(
if (messageQueue)
{
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
auto *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
webapiFormatChannelSettings(channelSettingsKeys, swgChannelSettings, settings, force);
MainCore::MsgChannelSettings *msg = MainCore::MsgChannelSettings::create(
this,
@ -702,7 +741,7 @@ void AMMod::sendChannelSettings(
}
void AMMod::webapiFormatChannelSettings(
QList<QString>& channelSettingsKeys,
const QList<QString>& channelSettingsKeys,
SWGSDRangel::SWGChannelSettings *swgChannelSettings,
const AMModSettings& settings,
bool force
@ -756,28 +795,28 @@ void AMMod::webapiFormatChannelSettings(
if (force)
{
const CWKeyerSettings& cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
const CWKeyerSettings& cwKeyerSettings = getCWKeyer()->getSettings();
swgAMModSettings->setCwKeyer(new SWGSDRangel::SWGCWKeyerSettings());
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = swgAMModSettings->getCwKeyer();
m_basebandSource->getCWKeyer().webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
CWKeyer::webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
}
if (settings.m_channelMarker && (channelSettingsKeys.contains("channelMarker") || force))
{
SWGSDRangel::SWGChannelMarker *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
auto *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
settings.m_channelMarker->formatTo(swgChannelMarker);
swgAMModSettings->setChannelMarker(swgChannelMarker);
}
if (settings.m_rollupState && (channelSettingsKeys.contains("rollupState") || force))
{
SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState();
auto *swgRollupState = new SWGSDRangel::SWGRollupState();
settings.m_rollupState->formatTo(swgRollupState);
swgAMModSettings->setRollupState(swgRollupState);
}
}
void AMMod::networkManagerFinished(QNetworkReply *reply)
void AMMod::networkManagerFinished(QNetworkReply *reply) const
{
QNetworkReply::NetworkError replyError = reply->error();
@ -800,25 +839,32 @@ void AMMod::networkManagerFinished(QNetworkReply *reply)
double AMMod::getMagSq() const
{
if (m_running) {
return m_basebandSource->getMagSq();
}
return 0;
}
CWKeyer *AMMod::getCWKeyer()
{
return &m_basebandSource->getCWKeyer();
}
void AMMod::setLevelMeter(QObject *levelMeter)
{
connect(m_basebandSource, SIGNAL(levelChanged(qreal, qreal, int)), levelMeter, SLOT(levelChanged(qreal, qreal, int)));
return &m_cwKeyer;
}
int AMMod::getAudioSampleRate() const
{
if (m_running) {
return m_basebandSource->getAudioSampleRate();
}
return 0;
}
int AMMod::getFeedbackAudioSampleRate() const
{
if (m_running) {
return m_basebandSource->getFeedbackAudioSampleRate();
}
return 0;
}

View File

@ -28,6 +28,7 @@
#include <QNetworkRequest>
#include "dsp/basebandsamplesource.h"
#include "dsp/cwkeyer.h"
#include "channel/channelapi.h"
#include "util/message.h"
@ -235,7 +236,7 @@ public:
uint32_t getNumberOfDeviceStreams() const;
double getMagSq() const;
CWKeyer *getCWKeyer();
void setLevelMeter(QObject *levelMeter);
void setLevelMeter(QObject *levelMeter) { m_levelMeter = levelMeter; }
int getAudioSampleRate() const;
int getFeedbackAudioSampleRate() const;
@ -250,6 +251,7 @@ private:
DeviceAPI* m_deviceAPI;
QThread *m_thread;
bool m_running = false;
AMModBaseband* m_basebandSource;
AMModSettings m_settings;
@ -258,36 +260,38 @@ private:
std::ifstream m_ifstream;
QString m_fileName;
quint64 m_fileSize; //!< raw file size (bytes)
quint32 m_recordLength; //!< record length in seconds computed from file size
int m_sampleRate;
quint64 m_fileSize = 0; //!< raw file size (bytes)
quint32 m_recordLength = 0; //!< record length in seconds computed from file size
int m_sampleRate = 48000;
QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
CWKeyer m_cwKeyer;
QObject *m_levelMeter = nullptr;
virtual bool handleMessage(const Message& cmd);
void applySettings(const AMModSettings& settings, bool force = false);
void sendSampleRateToDemodAnalyzer();
void sendSampleRateToDemodAnalyzer() const;
void openFileStream();
void seekFileStream(int seekPercentage);
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const AMModSettings& settings, bool force);
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) const;
void webapiReverseSendSettings(const QList<QString>& channelSettingsKeys, const AMModSettings& settings, bool force);
void webapiReverseSendCWSettings(const CWKeyerSettings& settings);
void sendChannelSettings(
const QList<ObjectPipe*>& pipes,
QList<QString>& channelSettingsKeys,
const QList<QString>& channelSettingsKeys,
const AMModSettings& settings,
bool force
);
void webapiFormatChannelSettings(
QList<QString>& channelSettingsKeys,
const QList<QString>& channelSettingsKeys,
SWGSDRangel::SWGChannelSettings *swgChannelSettings,
const AMModSettings& settings,
bool force
);
private slots:
void networkManagerFinished(QNetworkReply *reply);
void networkManagerFinished(QNetworkReply *reply) const;
};

View File

@ -21,6 +21,7 @@
#include "dsp/upchannelizer.h"
#include "dsp/dspengine.h"
#include "dsp/dspcommands.h"
#include "dsp/cwkeyer.h"
#include "ammodbaseband.h"
@ -171,8 +172,8 @@ bool AMModBaseband::handleMessage(const Message& cmd)
qDebug() << "AMModBaseband::handleMessage: MsgConfigureCWKeyer";
const CWKeyer::MsgConfigureCWKeyer& cfg = (CWKeyer::MsgConfigureCWKeyer&) cmd;
CWKeyer::MsgConfigureCWKeyer *notif = new CWKeyer::MsgConfigureCWKeyer(cfg);
CWKeyer& cwKeyer = m_source.getCWKeyer();
cwKeyer.getInputMessageQueue()->push(notif);
CWKeyer *cwKeyer = m_source.getCWKeyer();
cwKeyer->getInputMessageQueue()->push(notif);
return true;
}

View File

@ -63,7 +63,7 @@ public:
void reset();
void pull(const SampleVector::iterator& begin, unsigned int nbSamples);
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
CWKeyer& getCWKeyer() { return m_source.getCWKeyer(); }
void setCWKeyer(CWKeyer *cwKeyer) { m_source.setCWKeyer(cwKeyer); }
double getMagSq() const { return m_source.getMagSq(); }
int getAudioSampleRate() const { return m_source.getAudioSampleRate(); }
int getFeedbackAudioSampleRate() const { return m_source.getFeedbackAudioSampleRate(); }

View File

@ -45,7 +45,7 @@
AMModGUI* AMModGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx)
{
AMModGUI* gui = new AMModGUI(pluginAPI, deviceUISet, channelTx);
auto* gui = new AMModGUI(pluginAPI, deviceUISet, channelTx);
return gui;
}
@ -82,21 +82,23 @@ bool AMModGUI::handleMessage(const Message& message)
{
if (AMMod::MsgReportFileSourceStreamData::match(message))
{
m_recordSampleRate = ((AMMod::MsgReportFileSourceStreamData&)message).getSampleRate();
m_recordLength = ((AMMod::MsgReportFileSourceStreamData&)message).getRecordLength();
auto& cmd = (const AMMod::MsgReportFileSourceStreamData&) message;
m_recordSampleRate = cmd.getSampleRate();
m_recordLength = cmd.getRecordLength();
m_samplesCount = 0;
updateWithStreamData();
return true;
}
else if (AMMod::MsgReportFileSourceStreamTiming::match(message))
{
m_samplesCount = ((AMMod::MsgReportFileSourceStreamTiming&)message).getSamplesCount();
auto& cmd = (const AMMod::MsgReportFileSourceStreamTiming&) message;
m_samplesCount = (int) cmd.getSamplesCount();
updateWithStreamTime();
return true;
}
else if (AMMod::MsgConfigureAMMod::match(message))
{
const AMMod::MsgConfigureAMMod& cfg = (AMMod::MsgConfigureAMMod&) message;
auto& cfg = (const AMMod::MsgConfigureAMMod&) message;
m_settings = cfg.getSettings();
blockApplySettings(true);
m_channelMarker.updateSettings(static_cast<const ChannelMarker*>(m_settings.m_channelMarker));
@ -106,14 +108,14 @@ bool AMModGUI::handleMessage(const Message& message)
}
else if (CWKeyer::MsgConfigureCWKeyer::match(message))
{
const CWKeyer::MsgConfigureCWKeyer& cfg = (CWKeyer::MsgConfigureCWKeyer&) message;
auto& cfg = (const CWKeyer::MsgConfigureCWKeyer&) message;
ui->cwKeyerGUI->setSettings(cfg.getSettings());
ui->cwKeyerGUI->displaySettings();
return true;
}
else if (DSPSignalNotification::match(message))
{
const DSPSignalNotification& notif = (const DSPSignalNotification&) message;
auto& notif = (const DSPSignalNotification&) message;
m_deviceCenterFrequency = notif.getCenterFrequency();
m_basebandSampleRate = notif.getSampleRate();
ui->deltaFrequency->setValueRange(false, 7, -m_basebandSampleRate/2, m_basebandSampleRate/2);
@ -138,7 +140,7 @@ void AMModGUI::handleSourceMessages()
{
Message* message;
while ((message = getInputMessageQueue()->pop()) != 0)
while ((message = getInputMessageQueue()->pop()) != nullptr)
{
if (handleMessage(*message))
{
@ -149,7 +151,7 @@ void AMModGUI::handleSourceMessages()
void AMModGUI::on_deltaFrequency_changed(qint64 value)
{
m_channelMarker.setCenterFrequency(value);
m_channelMarker.setCenterFrequency((int) value);
m_settings.m_inputFrequencyOffset = value;
updateAbsoluteCenterFrequency();
applySettings();
@ -158,7 +160,7 @@ void AMModGUI::on_deltaFrequency_changed(qint64 value)
void AMModGUI::on_rfBW_valueChanged(int value)
{
ui->rfBWText->setText(QString("%1 kHz").arg(value / 10.0, 0, 'f', 1));
m_settings.m_rfBandwidth = value * 100.0;
m_settings.m_rfBandwidth = (float) value * 100.0f;
m_channelMarker.setBandwidth(value * 100);
applySettings();
}
@ -166,21 +168,21 @@ void AMModGUI::on_rfBW_valueChanged(int value)
void AMModGUI::on_modPercent_valueChanged(int value)
{
ui->modPercentText->setText(QString("%1").arg(value));
m_settings.m_modFactor = value / 100.0;
m_settings.m_modFactor = (float) value / 100.0f;
applySettings();
}
void AMModGUI::on_volume_valueChanged(int value)
{
ui->volumeText->setText(QString("%1").arg(value / 10.0, 0, 'f', 1));
m_settings.m_volumeFactor = value / 10.0;
m_settings.m_volumeFactor = (float) value / 10.0f;
applySettings();
}
void AMModGUI::on_toneFrequency_valueChanged(int value)
{
ui->toneFrequencyText->setText(QString("%1k").arg(value / 100.0, 0, 'f', 2));
m_settings.m_toneFrequency = value * 10.0;
m_settings.m_toneFrequency = (float) value * 10.0f;
applySettings();
}
@ -244,7 +246,7 @@ void AMModGUI::on_feedbackEnable_toggled(bool checked)
void AMModGUI::on_feedbackVolume_valueChanged(int value)
{
ui->feedbackVolumeText->setText(QString("%1").arg(value / 100.0, 0, 'f', 2));
m_settings.m_feedbackVolumeFactor = value / 100.0;
m_settings.m_feedbackVolumeFactor = (float) value / 100.0f;
applySettings();
}
@ -265,7 +267,7 @@ void AMModGUI::on_showFileDialog_clicked(bool checked)
{
(void) checked;
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open raw audio file"), ".", tr("Raw audio Files (*.raw)"), 0, QFileDialog::DontUseNativeDialog);
tr("Open raw audio file"), ".", tr("Raw audio Files (*.raw)"), nullptr, QFileDialog::DontUseNativeDialog);
if (fileName != "")
{
@ -283,7 +285,7 @@ void AMModGUI::configureFileName()
m_amMod->getInputMessageQueue()->push(message);
}
void AMModGUI::onWidgetRolled(QWidget* widget, bool rollDown)
void AMModGUI::onWidgetRolled(const QWidget* widget, bool rollDown)
{
(void) widget;
(void) rollDown;
@ -367,15 +369,15 @@ AMModGUI::AMModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampl
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
m_amMod = (AMMod*) channelTx;
m_amMod->setMessageQueueToGUI(getInputMessageQueue());
m_amMod->setMessageQueueToGUI(AMModGUI::getInputMessageQueue());
connect(&MainCore::instance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->mic);
connect(audioMuteRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioSelect(const QPoint &)));
m_audioMuteRightClickEnabler = new CRightClickEnabler(ui->mic);
connect(m_audioMuteRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioSelect(const QPoint &)));
CRightClickEnabler *feedbackRightClickEnabler = new CRightClickEnabler(ui->feedbackEnable);
connect(feedbackRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioFeedbackSelect(const QPoint &)));
m_feedbackRightClickEnabler = new CRightClickEnabler(ui->feedbackEnable);
connect(m_feedbackRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioFeedbackSelect(const QPoint &)));
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
@ -406,7 +408,7 @@ AMModGUI::AMModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampl
ui->cwKeyerGUI->setCWKeyer(m_amMod->getCWKeyer());
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages()));
connect(AMModGUI::getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages()));
m_amMod->setLevelMeter(ui->volumeMeter);
displaySettings();
@ -419,6 +421,8 @@ AMModGUI::AMModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampl
AMModGUI::~AMModGUI()
{
delete ui;
delete m_audioMuteRightClickEnabler;
delete m_feedbackRightClickEnabler;
}
void AMModGUI::blockApplySettings(bool block)
@ -439,9 +443,9 @@ void AMModGUI::applySettings(bool force)
void AMModGUI::displaySettings()
{
m_channelMarker.blockSignals(true);
m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
m_channelMarker.setCenterFrequency((int) m_settings.m_inputFrequencyOffset);
m_channelMarker.setTitle(m_settings.m_title);
m_channelMarker.setBandwidth(m_settings.m_rfBandwidth);
m_channelMarker.setBandwidth((int) m_settings.m_rfBandwidth);
m_channelMarker.blockSignals(false);
m_channelMarker.setColor(m_settings.m_rgbColor); // activate signal on the last setting only
@ -453,17 +457,17 @@ void AMModGUI::displaySettings()
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
ui->rfBW->setValue(roundf(m_settings.m_rfBandwidth / 100.0));
ui->rfBW->setValue((int) roundf(m_settings.m_rfBandwidth / 100.f));
ui->rfBWText->setText(QString("%1 kHz").arg(m_settings.m_rfBandwidth / 1000.0, 0, 'f', 1));
int modPercent = roundf(m_settings.m_modFactor * 100.0);
auto modPercent = (int) roundf(m_settings.m_modFactor * 100.0f);
ui->modPercent->setValue(modPercent);
ui->modPercentText->setText(QString("%1").arg(modPercent));
ui->toneFrequency->setValue(roundf(m_settings.m_toneFrequency / 10.0));
ui->toneFrequency->setValue((int) roundf(m_settings.m_toneFrequency / 10.0f));
ui->toneFrequencyText->setText(QString("%1k").arg(m_settings.m_toneFrequency / 1000.0, 0, 'f', 2));
ui->volume->setValue(roundf(m_settings.m_volumeFactor * 10.0));
ui->volume->setValue((int) roundf(m_settings.m_volumeFactor * 10.0f));
ui->volumeText->setText(QString("%1").arg(m_settings.m_volumeFactor, 0, 'f', 1));
ui->channelMute->setChecked(m_settings.m_channelMute);
@ -480,7 +484,7 @@ void AMModGUI::displaySettings()
ui->morseKeyer->setChecked(m_settings.m_modAFInput == AMModSettings::AMModInputAF::AMModInputCWTone);
ui->feedbackEnable->setChecked(m_settings.m_feedbackAudioEnable);
ui->feedbackVolume->setValue(roundf(m_settings.m_feedbackVolumeFactor * 100.0));
ui->feedbackVolume->setValue((int) roundf(m_settings.m_feedbackVolumeFactor * 100.0f));
ui->feedbackVolumeText->setText(QString("%1").arg(m_settings.m_feedbackVolumeFactor, 0, 'f', 2));
updateIndexLabel();
@ -605,7 +609,7 @@ void AMModGUI::updateWithStreamTime()
}
}
void AMModGUI::makeUIConnections()
void AMModGUI::makeUIConnections() const
{
QObject::connect(ui->deltaFrequency, &ValueDialZ::changed, this, &AMModGUI::on_deltaFrequency_changed);
QObject::connect(ui->rfBW, &QSlider::valueChanged, this, &AMModGUI::on_rfBW_valueChanged);

View File

@ -33,6 +33,7 @@ class DeviceUISet;
class AMMod;
class BasebandSampleSource;
class CRightClickEnabler;
namespace Ui {
class AMModGUI;
@ -45,21 +46,21 @@ public:
static AMModGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx);
virtual void destroy();
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; };
virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; };
virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; };
virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; };
virtual QString getTitle() const { return m_settings.m_title; };
virtual QColor getTitleColor() const { return m_settings.m_rgbColor; };
virtual void zetHidden(bool hidden) { m_settings.m_hidden = hidden; }
virtual bool getHidden() const { return m_settings.m_hidden; }
virtual ChannelMarker& getChannelMarker() { return m_channelMarker; }
virtual int getStreamIndex() const { return m_settings.m_streamIndex; }
virtual void setStreamIndex(int streamIndex) { m_settings.m_streamIndex = streamIndex; }
void resetToDefaults() final;
QByteArray serialize() const final;
bool deserialize(const QByteArray& data) final;
MessageQueue *getInputMessageQueue() final { return &m_inputMessageQueue; }
void setWorkspaceIndex(int index) final { m_settings.m_workspaceIndex = index; };
int getWorkspaceIndex() const final { return m_settings.m_workspaceIndex; };
void setGeometryBytes(const QByteArray& blob) final { m_settings.m_geometryBytes = blob; };
QByteArray getGeometryBytes() const final { return m_settings.m_geometryBytes; };
QString getTitle() const final { return m_settings.m_title; };
QColor getTitleColor() const final { return m_settings.m_rgbColor; };
void zetHidden(bool hidden) final { m_settings.m_hidden = hidden; }
bool getHidden() const final { return m_settings.m_hidden; }
ChannelMarker& getChannelMarker() final { return m_channelMarker; }
int getStreamIndex() const final { return m_settings.m_streamIndex; }
void setStreamIndex(int streamIndex) final { m_settings.m_streamIndex = streamIndex; }
public slots:
void channelMarkerChangedByCursor();
@ -75,6 +76,9 @@ private:
int m_basebandSampleRate;
bool m_doApplySettings;
CRightClickEnabler *m_audioMuteRightClickEnabler;
CRightClickEnabler *m_feedbackRightClickEnabler;
AMMod* m_amMod;
MovingAverageUtil<double, double, 20> m_channelPowerDbAvg;
@ -88,8 +92,8 @@ private:
bool m_enableNavTime;
MessageQueue m_inputMessageQueue;
explicit AMModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx, QWidget* parent = 0);
virtual ~AMModGUI();
explicit AMModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx, QWidget* parent = nullptr);
~AMModGUI() final;
void blockApplySettings(bool block);
void applySettings(bool force = false);
@ -97,11 +101,11 @@ private:
void updateWithStreamData();
void updateWithStreamTime();
bool handleMessage(const Message& message);
void makeUIConnections();
void makeUIConnections() const;
void updateAbsoluteCenterFrequency();
void leaveEvent(QEvent*);
void enterEvent(EnterEventType*);
void leaveEvent(QEvent*) final;
void enterEvent(EnterEventType*) final;
private slots:
void handleSourceMessages();
@ -124,7 +128,7 @@ private slots:
void on_feedbackEnable_toggled(bool checked);
void on_feedbackVolume_valueChanged(int value);
void onWidgetRolled(QWidget* widget, bool rollDown);
void onWidgetRolled(const QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p);
void configureFileName();

View File

@ -41,7 +41,7 @@ const PluginDescriptor AMModPlugin::m_pluginDescriptor = {
AMModPlugin::AMModPlugin(QObject* parent) :
QObject(parent),
m_pluginAPI(0)
m_pluginAPI(nullptr)
{
}
@ -62,7 +62,7 @@ void AMModPlugin::createTxChannel(DeviceAPI *deviceAPI, BasebandSampleSource **b
{
if (bs || cs)
{
AMMod *instance = new AMMod(deviceAPI);
auto *instance = new AMMod(deviceAPI);
if (bs) {
*bs = instance;

View File

@ -27,20 +27,20 @@
class DeviceUISet;
class BasebandSampleSource;
class AMModPlugin : public QObject, PluginInterface {
class AMModPlugin : public QObject, public PluginInterface {
Q_OBJECT
Q_INTERFACES(PluginInterface)
Q_PLUGIN_METADATA(IID "sdrangel.channeltx.ammod")
public:
explicit AMModPlugin(QObject* parent = 0);
explicit AMModPlugin(QObject* parent = nullptr);
const PluginDescriptor& getPluginDescriptor() const;
void initPlugin(PluginAPI* pluginAPI);
const PluginDescriptor& getPluginDescriptor() const final;
void initPlugin(PluginAPI* pluginAPI) final;
virtual void createTxChannel(DeviceAPI *deviceAPI, BasebandSampleSource **bs, ChannelAPI **cs) const;
virtual ChannelGUI* createTxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSource *txChannel) const;
virtual ChannelWebAPIAdapter* createChannelWebAPIAdapter() const;
void createTxChannel(DeviceAPI *deviceAPI, BasebandSampleSource **bs, ChannelAPI **cs) const final;
ChannelGUI* createTxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSource *txChannel) const final;
ChannelWebAPIAdapter* createChannelWebAPIAdapter() const final;
private:
static const PluginDescriptor m_pluginDescriptor;

View File

@ -19,6 +19,7 @@
#include <QDebug>
#include "dsp/datafifo.h"
#include "dsp/cwkeyer.h"
#include "util/messagequeue.h"
#include "maincore.h"
@ -27,15 +28,8 @@
const int AMModSource::m_levelNbSamples = 480; // every 10ms
AMModSource::AMModSource() :
m_channelSampleRate(48000),
m_channelFrequencyOffset(0),
m_audioSampleRate(48000),
m_audioFifo(12000),
m_feedbackAudioFifo(48000),
m_levelCalcCount(0),
m_peakLevel(0.0f),
m_levelSum(0.0f),
m_ifstream(nullptr)
m_feedbackAudioFifo(48000)
{
m_audioFifo.setLabel("AMModSource.m_audioFifo");
m_feedbackAudioFifo.setLabel("AMModSource.m_feedbackAudioFifo");
@ -55,9 +49,7 @@ AMModSource::AMModSource() :
applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true);
}
AMModSource::~AMModSource()
{
}
AMModSource::~AMModSource() = default;
void AMModSource::pull(SampleVector::iterator begin, unsigned int nbSamples)
{
@ -109,7 +101,7 @@ void AMModSource::pullOne(Sample& sample)
sample.m_real = (FixReal) ci.real();
sample.m_imag = (FixReal) ci.imag();
m_demodBuffer[m_demodBufferFill] = ci.real() + ci.imag();
m_demodBuffer[m_demodBufferFill] = (qint16) (ci.real() + ci.imag());
++m_demodBufferFill;
if (m_demodBufferFill >= m_demodBuffer.size())
@ -117,13 +109,11 @@ void AMModSource::pullOne(Sample& sample)
QList<ObjectPipe*> dataPipes;
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
if (dataPipes.size() > 0)
if (!dataPipes.empty())
{
QList<ObjectPipe*>::iterator it = dataPipes.begin();
for (; it != dataPipes.end(); ++it)
for (auto& dataPipe : dataPipes)
{
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
DataFifo *fifo = qobject_cast<DataFifo*>(dataPipe->m_element);
if (fifo) {
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
@ -137,7 +127,7 @@ void AMModSource::pullOne(Sample& sample)
void AMModSource::prefetch(unsigned int nbSamples)
{
unsigned int nbSamplesAudio = nbSamples * ((Real) m_audioSampleRate / (Real) m_channelSampleRate);
auto nbSamplesAudio = (nbSamples * (unsigned int) ((Real) m_audioSampleRate / (Real) m_channelSampleRate));
pullAudio(nbSamplesAudio);
}
@ -161,7 +151,7 @@ void AMModSource::pullAudio(unsigned int nbSamples)
void AMModSource::modulateSample()
{
Real t;
Real t = 0.0f;
pullAF(t);
@ -184,18 +174,13 @@ void AMModSource::pullAF(Real& sample)
sample = m_toneNco.next();
break;
case AMModSettings::AMModInputFile:
// sox f4exb_call.wav --encoding float --endian little f4exb_call.raw
// ffplay -f f32le -ar 48k -ac 1 f4exb_call.raw
if (m_ifstream && m_ifstream->is_open())
{
if (m_ifstream->eof())
{
if (m_settings.m_playLoop)
if ((m_ifstream->eof()) && (m_settings.m_playLoop))
{
m_ifstream->clear();
m_ifstream->seekg(0, std::ios::beg);
}
}
if (m_ifstream->eof())
{
@ -218,14 +203,18 @@ void AMModSource::pullAF(Real& sample)
case AMModSettings::AMModInputCWTone:
Real fadeFactor;
if (m_cwKeyer.getSample())
if (!m_cwKeyer) {
break;
}
if (m_cwKeyer->getSample())
{
m_cwKeyer.getCWSmoother().getFadeSample(true, fadeFactor);
m_cwKeyer->getCWSmoother().getFadeSample(true, fadeFactor);
sample = m_toneNco.next() * fadeFactor;
}
else
{
if (m_cwKeyer.getCWSmoother().getFadeSample(false, fadeFactor))
if (m_cwKeyer->getCWSmoother().getFadeSample(false, fadeFactor))
{
sample = m_toneNco.next() * fadeFactor;
}
@ -236,7 +225,6 @@ void AMModSource::pullAF(Real& sample)
}
}
break;
case AMModSettings::AMModInputNone:
default:
sample = 0.0f;
break;
@ -266,10 +254,10 @@ void AMModSource::pushFeedback(Real sample)
}
}
void AMModSource::processOneSample(Complex& ci)
void AMModSource::processOneSample(const Complex& ci)
{
m_feedbackAudioBuffer[m_feedbackAudioBufferFill].l = ci.real();
m_feedbackAudioBuffer[m_feedbackAudioBufferFill].r = ci.imag();
m_feedbackAudioBuffer[m_feedbackAudioBufferFill].l = (qint16) ci.real();
m_feedbackAudioBuffer[m_feedbackAudioBufferFill].r = (qint16) ci.imag();
++m_feedbackAudioBufferFill;
if (m_feedbackAudioBufferFill >= m_feedbackAudioBuffer.size())
@ -287,7 +275,7 @@ void AMModSource::processOneSample(Complex& ci)
}
}
void AMModSource::calculateLevel(Real& sample)
void AMModSource::calculateLevel(const Real& sample)
{
if (m_levelCalcCount < m_levelNbSamples)
{
@ -319,14 +307,18 @@ void AMModSource::applyAudioSampleRate(int sampleRate)
m_interpolatorConsumed = false;
m_interpolatorDistance = (Real) sampleRate / (Real) m_channelSampleRate;
m_interpolator.create(48, sampleRate, m_settings.m_rfBandwidth / 2.2, 3.0);
m_toneNco.setFreq(m_settings.m_toneFrequency, sampleRate);
m_cwKeyer.setSampleRate(sampleRate);
m_cwKeyer.reset();
m_toneNco.setFreq(m_settings.m_toneFrequency, (float) sampleRate);
if (m_cwKeyer)
{
m_cwKeyer->setSampleRate(sampleRate);
m_cwKeyer->reset();
}
QList<ObjectPipe*> pipes;
MainCore::instance()->getMessagePipes().getMessagePipes(m_channel, "reportdemod", pipes);
if (pipes.size() > 0)
if (!pipes.empty())
{
for (const auto& pipe : pipes)
{
@ -352,7 +344,7 @@ void AMModSource::applyFeedbackAudioSampleRate(int sampleRate)
m_feedbackInterpolatorDistanceRemain = 0;
m_feedbackInterpolatorDistance = (Real) sampleRate / (Real) m_audioSampleRate;
Real cutoff = std::min(sampleRate, m_audioSampleRate) / 2.2f;
Real cutoff = ((float) std::min(sampleRate, m_audioSampleRate)) / 2.2f;
m_feedbackInterpolator.create(48, sampleRate, cutoff, 3.0);
m_feedbackAudioSampleRate = sampleRate;
}
@ -365,9 +357,8 @@ void AMModSource::applySettings(const AMModSettings& settings, bool force)
applyAudioSampleRate(m_audioSampleRate);
}
if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || force)
{
m_toneNco.setFreq(settings.m_toneFrequency, m_audioSampleRate);
if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || force) {
m_toneNco.setFreq(settings.m_toneFrequency, (float) m_audioSampleRate);
}
if ((settings.m_modAFInput != m_settings.m_modAFInput) || force)
@ -391,7 +382,7 @@ void AMModSource::applyChannelSettings(int channelSampleRate, int channelFrequen
if ((channelFrequencyOffset != m_channelFrequencyOffset)
|| (channelSampleRate != m_channelSampleRate) || force)
{
m_carrierNco.setFreq(channelFrequencyOffset, channelSampleRate);
m_carrierNco.setFreq((float) channelFrequencyOffset, (float) channelSampleRate);
}
if ((channelSampleRate != m_channelSampleRate) || force)
@ -408,7 +399,6 @@ void AMModSource::applyChannelSettings(int channelSampleRate, int channelFrequen
void AMModSource::handleAudio()
{
QMutexLocker mlock(&m_mutex);
unsigned int nbRead;
while ((nbRead = m_audioFifo.read(reinterpret_cast<quint8*>(&m_audioReadBuffer[m_audioReadBufferFill]), 4096)) != 0)

View File

@ -31,23 +31,23 @@
#include "dsp/ncof.h"
#include "dsp/interpolator.h"
#include "util/movingaverage.h"
#include "dsp/cwkeyer.h"
#include "audio/audiofifo.h"
#include "ammodsettings.h"
class ChannelAPI;
class CWKeyer;
class AMModSource : public QObject, public ChannelSampleSource
{
Q_OBJECT
public:
AMModSource();
virtual ~AMModSource();
~AMModSource() final;
virtual void pull(SampleVector::iterator begin, unsigned int nbSamples);
virtual void pullOne(Sample& sample);
virtual void prefetch(unsigned int nbSamples);
void pull(SampleVector::iterator begin, unsigned int nbSamples) final;
void pullOne(Sample& sample) final;
void prefetch(unsigned int nbSamples) final;
void setInputFileStream(std::ifstream *ifstream) { m_ifstream = ifstream; }
AudioFifo *getAudioFifo() { return &m_audioFifo; }
@ -57,7 +57,8 @@ public:
void applyFeedbackAudioSampleRate(int sampleRate);
int getAudioSampleRate() const { return m_audioSampleRate; }
int getFeedbackAudioSampleRate() const { return m_feedbackAudioSampleRate; }
CWKeyer& getCWKeyer() { return m_cwKeyer; }
void setCWKeyer(CWKeyer *cwKeyer) { m_cwKeyer = cwKeyer; }
CWKeyer* getCWKeyer() { return m_cwKeyer; }
double getMagSq() const { return m_magsq; }
void getLevels(qreal& rmsLevel, qreal& peakLevel, int& numSamples) const
{
@ -69,8 +70,8 @@ public:
void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = false);
private:
int m_channelSampleRate;
int m_channelFrequencyOffset;
int m_channelSampleRate = 48000;
int m_channelFrequencyOffset = 0;
AMModSettings m_settings;
ChannelAPI *m_channel;
@ -90,7 +91,7 @@ private:
double m_magsq;
MovingAverageUtil<double, double, 16> m_movingAverage;
int m_audioSampleRate;
int m_audioSampleRate = 48000;
AudioVector m_audioBuffer;
unsigned int m_audioBufferFill;
AudioVector m_audioReadBuffer;
@ -105,24 +106,24 @@ private:
int m_demodBufferFill;
bool m_demodBufferEnabled;
quint32 m_levelCalcCount;
quint32 m_levelCalcCount = 0;
qreal m_rmsLevel;
qreal m_peakLevelOut;
Real m_peakLevel;
Real m_levelSum;
Real m_peakLevel = 0.0f;
Real m_levelSum = 0.0f;
std::ifstream *m_ifstream;
CWKeyer m_cwKeyer;
std::ifstream *m_ifstream = nullptr;
CWKeyer *m_cwKeyer = nullptr;
QRecursiveMutex m_mutex;
static const int m_levelNbSamples;
void processOneSample(Complex& ci);
void processOneSample(const Complex& ci);
void pullAF(Real& sample);
void pullAudio(unsigned int nbSamples);
void pushFeedback(Real sample);
void calculateLevel(Real& sample);
void calculateLevel(const Real& sample);
void modulateSample();
private slots:

View File

@ -56,19 +56,10 @@ const char* const NFMMod::m_channelId = "NFMMod";
NFMMod::NFMMod(DeviceAPI *deviceAPI) :
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSource),
m_deviceAPI(deviceAPI),
m_fileSize(0),
m_recordLength(0),
m_sampleRate(48000)
m_deviceAPI(deviceAPI)
{
setObjectName(m_channelId);
m_thread = new QThread(this);
m_basebandSource = new NFMModBaseband();
m_basebandSource->setInputFileStream(&m_ifstream);
m_basebandSource->setChannel(this);
m_basebandSource->moveToThread(m_thread);
applySettings(m_settings, true);
m_deviceAPI->addChannelSource(this);
@ -94,8 +85,8 @@ NFMMod::~NFMMod()
delete m_networkManager;
m_deviceAPI->removeChannelSourceAPI(this);
m_deviceAPI->removeChannelSource(this);
delete m_basebandSource;
delete m_thread;
NFMMod::stop();
}
void NFMMod::setDeviceAPI(DeviceAPI *deviceAPI)
@ -112,21 +103,61 @@ void NFMMod::setDeviceAPI(DeviceAPI *deviceAPI)
void NFMMod::start()
{
if (m_running) {
return;
}
qDebug("NFMMod::start");
m_thread = new QThread(this);
m_basebandSource = new NFMModBaseband();
m_basebandSource->setInputFileStream(&m_ifstream);
m_basebandSource->setChannel(this);
m_basebandSource->reset();
m_basebandSource->setCWKeyer(&m_cwKeyer);
m_basebandSource->moveToThread(m_thread);
QObject::connect(
m_thread,
&QThread::finished,
m_basebandSource,
&QObject::deleteLater
);
QObject::connect(
m_thread,
&QThread::finished,
m_thread,
&QThread::deleteLater
);
m_thread->start();
if (m_levelMeter) {
connect(m_basebandSource, SIGNAL(levelChanged(qreal, qreal, int)), m_levelMeter, SLOT(levelChanged(qreal, qreal, int)));
}
NFMModBaseband::MsgConfigureNFMModBaseband *msg = NFMModBaseband::MsgConfigureNFMModBaseband::create(m_settings, true);
m_basebandSource->getInputMessageQueue()->push(msg);
m_running = true;
}
void NFMMod::stop()
{
if (!m_running) {
return;
}
qDebug("NFMMod::stop");
m_thread->exit();
m_running = false;
m_thread->quit();
m_thread->wait();
}
void NFMMod::pull(SampleVector::iterator& begin, unsigned int nbSamples)
{
if (m_running) {
m_basebandSource->pull(begin, nbSamples);
}
}
void NFMMod::setCenterFrequency(qint64 frequency)
@ -146,7 +177,7 @@ bool NFMMod::handleMessage(const Message& cmd)
{
if (MsgConfigureNFMMod::match(cmd))
{
MsgConfigureNFMMod& cfg = (MsgConfigureNFMMod&) cmd;
auto& cfg = (const MsgConfigureNFMMod&) cmd;
qDebug() << "NFMMod::handleMessage: MsgConfigureNFMMod";
applySettings(cfg.getSettings(), cfg.getForce());
@ -155,7 +186,7 @@ bool NFMMod::handleMessage(const Message& cmd)
}
else if (MsgConfigureFileSourceName::match(cmd))
{
MsgConfigureFileSourceName& conf = (MsgConfigureFileSourceName&) cmd;
auto& conf = (const MsgConfigureFileSourceName&) cmd;
m_fileName = conf.getFileName();
openFileStream();
qDebug() << "NFMMod::handleMessage: MsgConfigureFileSourceName:"
@ -164,7 +195,7 @@ bool NFMMod::handleMessage(const Message& cmd)
}
else if (MsgConfigureFileSourceSeek::match(cmd))
{
MsgConfigureFileSourceSeek& conf = (MsgConfigureFileSourceSeek&) cmd;
auto& conf = (const MsgConfigureFileSourceSeek&) cmd;
int seekPercentage = conf.getPercentage();
seekFileStream(seekPercentage);
qDebug() << "NFMMod::handleMessage: MsgConfigureFileSourceSeek:"
@ -190,7 +221,7 @@ bool NFMMod::handleMessage(const Message& cmd)
}
else if (MsgConfigureFileSourceName::match(cmd))
{
MsgConfigureFileSourceName& conf = (MsgConfigureFileSourceName&) cmd;
auto& conf = (const MsgConfigureFileSourceName&) cmd;
m_fileName = conf.getFileName();
openFileStream();
qDebug() << "NFMMod::handleMessage: MsgConfigureFileSourceName:"
@ -199,7 +230,7 @@ bool NFMMod::handleMessage(const Message& cmd)
}
else if (MsgConfigureFileSourceSeek::match(cmd))
{
MsgConfigureFileSourceSeek& conf = (MsgConfigureFileSourceSeek&) cmd;
auto& conf = (const MsgConfigureFileSourceSeek&) cmd;
int seekPercentage = conf.getPercentage();
seekFileStream(seekPercentage);
qDebug() << "NFMMod::handleMessage: MsgConfigureFileSourceSeek:"
@ -225,7 +256,7 @@ bool NFMMod::handleMessage(const Message& cmd)
}
else if (CWKeyer::MsgConfigureCWKeyer::match(cmd))
{
const CWKeyer::MsgConfigureCWKeyer& cfg = (CWKeyer::MsgConfigureCWKeyer&) cmd;
auto& cfg = (const CWKeyer::MsgConfigureCWKeyer&) cmd;
if (m_settings.m_useReverseAPI) {
webapiReverseSendCWSettings(cfg.getSettings());
@ -236,14 +267,17 @@ bool NFMMod::handleMessage(const Message& cmd)
else if (DSPSignalNotification::match(cmd))
{
// Forward to the source
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy
if (m_running)
{
auto& notif = (const DSPSignalNotification&) cmd;
auto* rep = new DSPSignalNotification(notif); // make a copy
qDebug() << "NFMMod::handleMessage: DSPSignalNotification";
m_basebandSource->getInputMessageQueue()->push(rep);
// Forward to GUI if any
if (getMessageQueueToGUI()) {
getMessageQueueToGUI()->push(new DSPSignalNotification(notif));
}
}
return true;
}
@ -271,7 +305,7 @@ void NFMMod::openFileStream()
m_ifstream.seekg(0,std::ios_base::beg);
m_sampleRate = 48000; // fixed rate
m_recordLength = m_fileSize / (sizeof(Real) * m_sampleRate);
m_recordLength = (quint32) (m_fileSize / (sizeof(Real) * m_sampleRate));
qDebug() << "NFMMod::openFileStream: " << m_fileName.toStdString().c_str()
<< " fileSize: " << m_fileSize << "bytes"
@ -386,8 +420,11 @@ void NFMMod::applySettings(const NFMModSettings& settings, bool force)
reverseAPIKeys.append("streamIndex");
}
if (m_running)
{
NFMModBaseband::MsgConfigureNFMModBaseband *msg = NFMModBaseband::MsgConfigureNFMModBaseband::create(settings, force);
m_basebandSource->getInputMessageQueue()->push(msg);
}
if (settings.m_useReverseAPI)
{
@ -402,7 +439,7 @@ void NFMMod::applySettings(const NFMModSettings& settings, bool force)
QList<ObjectPipe*> pipes;
MainCore::instance()->getMessagePipes().getMessagePipes(this, "settings", pipes);
if (pipes.size() > 0) {
if (!pipes.empty()) {
sendChannelSettings(pipes, reverseAPIKeys, settings, force);
}
@ -430,12 +467,12 @@ bool NFMMod::deserialize(const QByteArray& data)
return success;
}
void NFMMod::sendSampleRateToDemodAnalyzer()
void NFMMod::sendSampleRateToDemodAnalyzer() const
{
QList<ObjectPipe*> pipes;
MainCore::instance()->getMessagePipes().getMessagePipes(this, "reportdemod", pipes);
if (pipes.size() > 0)
if (!pipes.empty())
{
for (const auto& pipe : pipes)
{
@ -459,7 +496,7 @@ int NFMMod::webapiSettingsGet(
webapiFormatChannelSettings(response, m_settings);
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = response.getNfmModSettings()->getCwKeyer();
const CWKeyerSettings& cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
const CWKeyerSettings& cwKeyerSettings = getCWKeyer()->getSettings();
CWKeyer::webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
return 200;
@ -487,11 +524,11 @@ int NFMMod::webapiSettingsPutPatch(
if (channelSettingsKeys.contains("cwKeyer"))
{
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = response.getNfmModSettings()->getCwKeyer();
CWKeyerSettings cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
CWKeyerSettings cwKeyerSettings = getCWKeyer()->getSettings();
CWKeyer::webapiSettingsPutPatch(channelSettingsKeys, cwKeyerSettings, apiCwKeyerSettings);
CWKeyer::MsgConfigureCWKeyer *msgCwKeyer = CWKeyer::MsgConfigureCWKeyer::create(cwKeyerSettings, force);
m_basebandSource->getCWKeyer().getInputMessageQueue()->push(msgCwKeyer);
getCWKeyer()->getInputMessageQueue()->push(msgCwKeyer);
if (m_guiMessageQueue) // forward to GUI if any
{
@ -583,13 +620,13 @@ void NFMMod::webapiUpdateChannelSettings(
settings.m_reverseAPIAddress = *response.getNfmModSettings()->getReverseApiAddress();
}
if (channelSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getNfmModSettings()->getReverseApiPort();
settings.m_reverseAPIPort = (uint16_t) response.getNfmModSettings()->getReverseApiPort();
}
if (channelSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getNfmModSettings()->getReverseApiDeviceIndex();
settings.m_reverseAPIDeviceIndex = (uint16_t) response.getNfmModSettings()->getReverseApiDeviceIndex();
}
if (channelSettingsKeys.contains("reverseAPIChannelIndex")) {
settings.m_reverseAPIChannelIndex = response.getNfmModSettings()->getReverseApiChannelIndex();
settings.m_reverseAPIChannelIndex = (uint16_t) response.getNfmModSettings()->getReverseApiChannelIndex();
}
if (settings.m_channelMarker && channelSettingsKeys.contains("channelMarker")) {
settings.m_channelMarker->updateFrom(channelSettingsKeys, response.getNfmModSettings()->getChannelMarker());
@ -667,7 +704,7 @@ void NFMMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respon
}
else
{
SWGSDRangel::SWGChannelMarker *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
auto *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
settings.m_channelMarker->formatTo(swgChannelMarker);
response.getNfmModSettings()->setChannelMarker(swgChannelMarker);
}
@ -681,23 +718,27 @@ void NFMMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respon
}
else
{
SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState();
auto *swgRollupState = new SWGSDRangel::SWGRollupState();
settings.m_rollupState->formatTo(swgRollupState);
response.getNfmModSettings()->setRollupState(swgRollupState);
}
}
}
void NFMMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
void NFMMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) const
{
response.getNfmModReport()->setChannelPowerDb(CalcDb::dbPower(getMagSq()));
response.getNfmModReport()->setChannelPowerDb((float) CalcDb::dbPower(getMagSq()));
if (m_running)
{
response.getNfmModReport()->setAudioSampleRate(m_basebandSource->getAudioSampleRate());
response.getNfmModReport()->setChannelSampleRate(m_basebandSource->getChannelSampleRate());
}
}
void NFMMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const NFMModSettings& settings, bool force)
void NFMMod::webapiReverseSendSettings(const QList<QString>& channelSettingsKeys, const NFMModSettings& settings, bool force)
{
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
auto *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
webapiFormatChannelSettings(channelSettingsKeys, swgChannelSettings, settings, force);
QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
@ -708,8 +749,8 @@ void NFMMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, cons
m_networkRequest.setUrl(QUrl(channelSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgChannelSettings->asJson().toUtf8());
buffer->seek(0);
@ -722,7 +763,7 @@ void NFMMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, cons
void NFMMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
{
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
auto *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
swgChannelSettings->setDirection(1); // single source (Tx)
swgChannelSettings->setChannelType(new QString("NFMMod"));
swgChannelSettings->setNfmModSettings(new SWGSDRangel::SWGNFMModSettings());
@ -730,7 +771,7 @@ void NFMMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
swgNFModSettings->setCwKeyer(new SWGSDRangel::SWGCWKeyerSettings());
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = swgNFModSettings->getCwKeyer();
m_basebandSource->getCWKeyer().webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
CWKeyer::webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
.arg(m_settings.m_reverseAPIAddress)
@ -740,8 +781,8 @@ void NFMMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
m_networkRequest.setUrl(QUrl(channelSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgChannelSettings->asJson().toUtf8());
buffer->seek(0);
@ -754,7 +795,7 @@ void NFMMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
void NFMMod::sendChannelSettings(
const QList<ObjectPipe*>& pipes,
QList<QString>& channelSettingsKeys,
const QList<QString>& channelSettingsKeys,
const NFMModSettings& settings,
bool force)
{
@ -764,7 +805,7 @@ void NFMMod::sendChannelSettings(
if (messageQueue)
{
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
auto *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
webapiFormatChannelSettings(channelSettingsKeys, swgChannelSettings, settings, force);
MainCore::MsgChannelSettings *msg = MainCore::MsgChannelSettings::create(
this,
@ -778,7 +819,7 @@ void NFMMod::sendChannelSettings(
}
void NFMMod::webapiFormatChannelSettings(
QList<QString>& channelSettingsKeys,
const QList<QString>& channelSettingsKeys,
SWGSDRangel::SWGChannelSettings *swgChannelSettings,
const NFMModSettings& settings,
bool force
@ -856,28 +897,28 @@ void NFMMod::webapiFormatChannelSettings(
if (settings.m_channelMarker && (channelSettingsKeys.contains("channelMarker") || force))
{
SWGSDRangel::SWGChannelMarker *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
auto *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
settings.m_channelMarker->formatTo(swgChannelMarker);
swgNFMModSettings->setChannelMarker(swgChannelMarker);
}
if (settings.m_rollupState && (channelSettingsKeys.contains("rollupState") || force))
{
SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState();
auto *swgRollupState = new SWGSDRangel::SWGRollupState();
settings.m_rollupState->formatTo(swgRollupState);
swgNFMModSettings->setRollupState(swgRollupState);
}
if (force)
{
const CWKeyerSettings& cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
const CWKeyerSettings& cwKeyerSettings = getCWKeyer()->getSettings();
swgNFMModSettings->setCwKeyer(new SWGSDRangel::SWGCWKeyerSettings());
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = swgNFMModSettings->getCwKeyer();
m_basebandSource->getCWKeyer().webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
CWKeyer::webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
}
}
void NFMMod::networkManagerFinished(QNetworkReply *reply)
void NFMMod::networkManagerFinished(QNetworkReply *reply) const
{
QNetworkReply::NetworkError replyError = reply->error();
@ -900,17 +941,11 @@ void NFMMod::networkManagerFinished(QNetworkReply *reply)
double NFMMod::getMagSq() const
{
if (m_running) {
return m_basebandSource->getMagSq();
}
}
CWKeyer *NFMMod::getCWKeyer()
{
return &m_basebandSource->getCWKeyer();
}
void NFMMod::setLevelMeter(QObject *levelMeter)
{
connect(m_basebandSource, SIGNAL(levelChanged(qreal, qreal, int)), levelMeter, SLOT(levelChanged(qreal, qreal, int)));
return 0;
}
uint32_t NFMMod::getNumberOfDeviceStreams() const
@ -920,10 +955,18 @@ uint32_t NFMMod::getNumberOfDeviceStreams() const
int NFMMod::getAudioSampleRate() const
{
if (m_running) {
return m_basebandSource->getAudioSampleRate();
}
return 0;
}
int NFMMod::getFeedbackAudioSampleRate() const
{
if (m_running) {
return m_basebandSource->getFeedbackAudioSampleRate();
}
return 0;
}

View File

@ -28,6 +28,7 @@
#include <QNetworkRequest>
#include "dsp/basebandsamplesource.h"
#include "dsp/cwkeyer.h"
#include "channel/channelapi.h"
#include "util/message.h"
@ -81,7 +82,7 @@ public:
private:
QString m_fileName;
MsgConfigureFileSourceName(const QString& fileName) :
explicit MsgConfigureFileSourceName(const QString& fileName) :
Message(),
m_fileName(fileName)
{ }
@ -99,10 +100,10 @@ public:
return new MsgConfigureFileSourceSeek(seekPercentage);
}
protected:
private:
int m_seekPercentage; //!< percentage of seek position from the beginning 0..100
MsgConfigureFileSourceSeek(int seekPercentage) :
explicit MsgConfigureFileSourceSeek(int seekPercentage) :
Message(),
m_seekPercentage(seekPercentage)
{ }
@ -137,10 +138,10 @@ public:
return new MsgReportFileSourceStreamTiming(samplesCount);
}
protected:
private:
std::size_t m_samplesCount;
MsgReportFileSourceStreamTiming(std::size_t samplesCount) :
explicit MsgReportFileSourceStreamTiming(std::size_t samplesCount) :
Message(),
m_samplesCount(samplesCount)
{ }
@ -159,7 +160,7 @@ public:
return new MsgReportFileSourceStreamData(sampleRate, recordLength);
}
protected:
private:
int m_sampleRate;
quint32 m_recordLength;
@ -173,55 +174,55 @@ public:
//=================================================================
NFMMod(DeviceAPI *deviceAPI);
virtual ~NFMMod();
virtual void destroy() { delete this; }
virtual void setDeviceAPI(DeviceAPI *deviceAPI);
virtual DeviceAPI *getDeviceAPI() { return m_deviceAPI; }
explicit NFMMod(DeviceAPI *deviceAPI);
~NFMMod() final;
void destroy() final { delete this; }
void setDeviceAPI(DeviceAPI *deviceAPI) final;
DeviceAPI *getDeviceAPI() final { return m_deviceAPI; }
virtual void start();
virtual void stop();
virtual void pull(SampleVector::iterator& begin, unsigned int nbSamples);
virtual void pushMessage(Message *msg) { m_inputMessageQueue.push(msg); }
virtual QString getSourceName() { return objectName(); }
void start() final;
void stop() final;
void pull(SampleVector::iterator& begin, unsigned int nbSamples) final;
void pushMessage(Message *msg) final { m_inputMessageQueue.push(msg); }
QString getSourceName() final { return objectName(); }
virtual void getIdentifier(QString& id) { id = objectName(); }
virtual QString getIdentifier() const { return objectName(); }
virtual void getTitle(QString& title) { title = m_settings.m_title; }
virtual qint64 getCenterFrequency() const { return m_settings.m_inputFrequencyOffset; }
virtual void setCenterFrequency(qint64 frequency);
void getIdentifier(QString& id) final { id = objectName(); }
QString getIdentifier() const final { return objectName(); }
void getTitle(QString& title) final { title = m_settings.m_title; }
qint64 getCenterFrequency() const final { return m_settings.m_inputFrequencyOffset; }
void setCenterFrequency(qint64 frequency) final;
virtual QByteArray serialize() const;
virtual bool deserialize(const QByteArray& data);
QByteArray serialize() const final;
bool deserialize(const QByteArray& data) final;
virtual int getNbSinkStreams() const { return 1; }
virtual int getNbSourceStreams() const { return 0; }
virtual int getStreamIndex() const { return m_settings.m_streamIndex; }
int getNbSinkStreams() const final { return 1; }
int getNbSourceStreams() const final { return 0; }
int getStreamIndex() const final { return m_settings.m_streamIndex; }
virtual qint64 getStreamCenterFrequency(int streamIndex, bool sinkElseSource) const
qint64 getStreamCenterFrequency(int streamIndex, bool sinkElseSource) const final
{
(void) streamIndex;
(void) sinkElseSource;
return m_settings.m_inputFrequencyOffset;
}
virtual int webapiSettingsGet(
int webapiSettingsGet(
SWGSDRangel::SWGChannelSettings& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiWorkspaceGet(
int webapiWorkspaceGet(
SWGSDRangel::SWGWorkspaceInfo& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiSettingsPutPatch(
int webapiSettingsPutPatch(
bool force,
const QStringList& channelSettingsKeys,
SWGSDRangel::SWGChannelSettings& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiReportGet(
int webapiReportGet(
SWGSDRangel::SWGChannelReport& response,
QString& errorMessage);
QString& errorMessage) final;
static void webapiFormatChannelSettings(
SWGSDRangel::SWGChannelSettings& response,
@ -233,8 +234,8 @@ public:
SWGSDRangel::SWGChannelSettings& response);
double getMagSq() const;
CWKeyer *getCWKeyer();
void setLevelMeter(QObject *levelMeter);
CWKeyer *getCWKeyer() { return &m_cwKeyer; }
void setLevelMeter(QObject *levelMeter) { m_levelMeter = levelMeter; }
uint32_t getNumberOfDeviceStreams() const;
int getAudioSampleRate() const;
int getFeedbackAudioSampleRate() const;
@ -250,6 +251,7 @@ private:
DeviceAPI* m_deviceAPI;
QThread *m_thread;
bool m_running = false;
NFMModBaseband* m_basebandSource;
NFMModSettings m_settings;
@ -258,36 +260,39 @@ private:
std::ifstream m_ifstream;
QString m_fileName;
quint64 m_fileSize; //!< raw file size (bytes)
quint32 m_recordLength; //!< record length in seconds computed from file size
int m_sampleRate;
quint64 m_fileSize = 0; //!< raw file size (bytes)
quint32 m_recordLength = 0; //!< record length in seconds computed from file size
int m_sampleRate = 48000;
QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
virtual bool handleMessage(const Message& cmd);
CWKeyer m_cwKeyer;
QObject *m_levelMeter = nullptr;
bool handleMessage(const Message& cmd) final;
void applySettings(const NFMModSettings& settings, bool force = false);
void sendSampleRateToDemodAnalyzer();
void sendSampleRateToDemodAnalyzer() const;
void openFileStream();
void seekFileStream(int seekPercentage);
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const NFMModSettings& settings, bool force);
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) const;
void webapiReverseSendSettings(const QList<QString>& channelSettingsKeys, const NFMModSettings& settings, bool force);
void webapiReverseSendCWSettings(const CWKeyerSettings& settings);
void sendChannelSettings(
const QList<ObjectPipe*>& pipes,
QList<QString>& channelSettingsKeys,
const QList<QString>& channelSettingsKeys,
const NFMModSettings& settings,
bool force
);
void webapiFormatChannelSettings(
QList<QString>& channelSettingsKeys,
const QList<QString>& channelSettingsKeys,
SWGSDRangel::SWGChannelSettings *swgChannelSettings,
const NFMModSettings& settings,
bool force
);
private slots:
void networkManagerFinished(QNetworkReply *reply);
void networkManagerFinished(QNetworkReply *reply) const;
};

View File

@ -21,6 +21,7 @@
#include "dsp/upchannelizer.h"
#include "dsp/dspengine.h"
#include "dsp/dspcommands.h"
#include "dsp/cwkeyer.h"
#include "nfmmodbaseband.h"
@ -170,8 +171,8 @@ bool NFMModBaseband::handleMessage(const Message& cmd)
QMutexLocker mutexLocker(&m_mutex);
const CWKeyer::MsgConfigureCWKeyer& cfg = (CWKeyer::MsgConfigureCWKeyer&) cmd;
CWKeyer::MsgConfigureCWKeyer *notif = new CWKeyer::MsgConfigureCWKeyer(cfg);
CWKeyer& cwKeyer = m_source.getCWKeyer();
cwKeyer.getInputMessageQueue()->push(notif);
CWKeyer *cwKeyer = m_source.getCWKeyer();
cwKeyer->getInputMessageQueue()->push(notif);
return true;
}

View File

@ -63,7 +63,7 @@ public:
void reset();
void pull(const SampleVector::iterator& begin, unsigned int nbSamples);
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
CWKeyer& getCWKeyer() { return m_source.getCWKeyer(); }
void setCWKeyer(CWKeyer *cwKeyer) { m_source.setCWKeyer(cwKeyer); }
double getMagSq() const { return m_source.getMagSq(); }
int getAudioSampleRate() const { return m_source.getAudioSampleRate(); }
int getFeedbackAudioSampleRate() const { return m_source.getFeedbackAudioSampleRate(); }

View File

@ -20,26 +20,19 @@
#include "dsp/datafifo.h"
#include "dsp/misc.h"
#include "dsp/cwkeyer.h"
#include "util/messagequeue.h"
#include "maincore.h"
#include "nfmmodsource.h"
const int NFMModSource::m_levelNbSamples = 480; // every 10ms
const float NFMModSource::m_preemphasis = 120.0e-6; // 120us
const float NFMModSource::m_preemphasis = 120.0e-6f; // 120us
NFMModSource::NFMModSource() :
m_channelSampleRate(48000),
m_channelFrequencyOffset(0),
m_modPhasor(0.0f),
m_preemphasisFilter(m_preemphasis*48000),
m_audioSampleRate(48000),
m_audioFifo(12000),
m_feedbackAudioFifo(48000),
m_levelCalcCount(0),
m_peakLevel(0.0f),
m_levelSum(0.0f),
m_ifstream(nullptr)
m_feedbackAudioFifo(48000)
{
m_audioFifo.setLabel("NFMModSource.m_audioFifo");
m_feedbackAudioFifo.setLabel("NFMModSource.m_feedbackAudioFifo");
@ -62,7 +55,7 @@ NFMModSource::NFMModSource() :
-20, // threshold (dB)
20, // knee (dB)
15, // ratio (dB)
0.003, // attack (s)
0.003f,// attack (s)
0.25 // release (s)
);
@ -70,9 +63,7 @@ NFMModSource::NFMModSource() :
applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true);
}
NFMModSource::~NFMModSource()
{
}
NFMModSource::~NFMModSource() = default;
void NFMModSource::pull(SampleVector::iterator begin, unsigned int nbSamples)
{
@ -128,7 +119,7 @@ void NFMModSource::pullOne(Sample& sample)
void NFMModSource::prefetch(unsigned int nbSamples)
{
unsigned int nbSamplesAudio = nbSamples * ((Real) m_audioSampleRate / (Real) m_channelSampleRate);
unsigned int nbSamplesAudio = (nbSamples * (unsigned int) ((Real) m_audioSampleRate / (Real) m_channelSampleRate));
pullAudio(nbSamplesAudio);
}
@ -152,7 +143,9 @@ void NFMModSource::pullAudio(unsigned int nbSamplesAudio)
void NFMModSource::modulateSample()
{
Real t0, t1, t;
Real t0 = 0.0f;
Real t1 = 0.0f;
Real t = 0.0f;
pullAF(t0);
@ -171,24 +164,24 @@ void NFMModSource::modulateSample()
if (m_settings.m_ctcssOn) {
t1 = 0.85f * m_bandpass.filter(t) + 0.15f * 0.625f * m_ctcssNco.next();
} else if (m_settings.m_dcsOn) {
t1 = 0.9f * m_bandpass.filter(t) + 0.1f * 0.625f * m_dcsMod.next();
t1 = 0.9f * m_bandpass.filter(t) + 0.1f * 0.625f * (float) m_dcsMod.next();
} else if (m_settings.m_bpfOn) {
t1 = m_bandpass.filter(t);
} else {
t1 = m_lowpass.filter(t);
}
m_modPhasor += (M_PI * m_settings.m_fmDeviation / (float) m_audioSampleRate) * t1;
m_modPhasor += (float) ((M_PI * m_settings.m_fmDeviation / (float) m_audioSampleRate) * t1);
// limit phasor range to ]-pi,pi]
if (m_modPhasor > M_PI) {
m_modPhasor -= (2.0f * M_PI);
m_modPhasor -= (float) (2.0 * M_PI);
}
m_modSample.real(cos(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF); // -1 dB
m_modSample.imag(sin(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF);
m_modSample.real((float) (cos(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF)); // -1 dB
m_modSample.imag((float) (sin(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF));
m_demodBuffer[m_demodBufferFill] = t1 * std::numeric_limits<int16_t>::max();
m_demodBuffer[m_demodBufferFill] = (qint16) (t1 * std::numeric_limits<int16_t>::max());
++m_demodBufferFill;
if (m_demodBufferFill >= m_demodBuffer.size())
@ -196,13 +189,11 @@ void NFMModSource::modulateSample()
QList<ObjectPipe*> dataPipes;
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
if (dataPipes.size() > 0)
if (!dataPipes.empty())
{
QList<ObjectPipe*>::iterator it = dataPipes.begin();
for (; it != dataPipes.end(); ++it)
for (auto& dataPipe : dataPipes)
{
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
DataFifo *fifo = qobject_cast<DataFifo*>(dataPipe->m_element);
if (fifo) {
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
@ -222,18 +213,13 @@ void NFMModSource::pullAF(Real& sample)
sample = m_toneNco.next();
break;
case NFMModSettings::NFMModInputFile:
// sox f4exb_call.wav --encoding float --endian little f4exb_call.raw
// ffplay -f f32le -ar 48k -ac 1 f4exb_call.raw
if (m_ifstream && m_ifstream->is_open())
{
if (m_ifstream->eof())
{
if (m_settings.m_playLoop)
if (m_ifstream->eof() && m_settings.m_playLoop)
{
m_ifstream->clear();
m_ifstream->seekg(0, std::ios::beg);
}
}
if (m_ifstream->eof())
{
@ -267,8 +253,8 @@ void NFMModSource::pullAF(Real& sample)
}
else
{
unsigned int size = m_audioBuffer.size();
qDebug("NFMModSource::pullAF: starve audio samples: size: %u", size);
std::size_t size = m_audioBuffer.size();
qDebug("NFMModSource::pullAF: starve audio samples: size: %lu", size);
sample = ((m_audioBuffer[size-1].l + m_audioBuffer[size-1].r) / 65536.0f) * m_settings.m_volumeFactor;
}
@ -276,14 +262,18 @@ void NFMModSource::pullAF(Real& sample)
case NFMModSettings::NFMModInputCWTone:
Real fadeFactor;
if (m_cwKeyer.getSample())
if (!m_cwKeyer) {
break;
}
if (m_cwKeyer->getSample())
{
m_cwKeyer.getCWSmoother().getFadeSample(true, fadeFactor);
m_cwKeyer->getCWSmoother().getFadeSample(true, fadeFactor);
sample = m_toneNco.next() * fadeFactor;
}
else
{
if (m_cwKeyer.getCWSmoother().getFadeSample(false, fadeFactor))
if (m_cwKeyer->getCWSmoother().getFadeSample(false, fadeFactor))
{
sample = m_toneNco.next() * fadeFactor;
}
@ -294,7 +284,6 @@ void NFMModSource::pullAF(Real& sample)
}
}
break;
case NFMModSettings::NFMModInputNone:
default:
sample = 0.0f;
break;
@ -324,10 +313,10 @@ void NFMModSource::pushFeedback(Real sample)
}
}
void NFMModSource::processOneSample(Complex& ci)
void NFMModSource::processOneSample(const Complex& ci)
{
m_feedbackAudioBuffer[m_feedbackAudioBufferFill].l = ci.real();
m_feedbackAudioBuffer[m_feedbackAudioBufferFill].r = ci.imag();
m_feedbackAudioBuffer[m_feedbackAudioBufferFill].l = (qint16) ci.real();
m_feedbackAudioBuffer[m_feedbackAudioBufferFill].r = (qint16) ci.imag();
++m_feedbackAudioBufferFill;
if (m_feedbackAudioBufferFill >= m_feedbackAudioBuffer.size())
@ -345,7 +334,7 @@ void NFMModSource::processOneSample(Complex& ci)
}
}
void NFMModSource::calculateLevel(Real& sample)
void NFMModSource::calculateLevel(const Real& sample)
{
if (m_levelCalcCount < m_levelNbSamples)
{
@ -379,13 +368,18 @@ void NFMModSource::applyAudioSampleRate(int sampleRate)
m_interpolator.create(48, sampleRate, m_settings.m_rfBandwidth / 2.2, 3.0);
m_lowpass.create(301, sampleRate, m_settings.m_afBandwidth);
m_bandpass.create(301, sampleRate, 300.0, m_settings.m_afBandwidth);
m_toneNco.setFreq(m_settings.m_toneFrequency, sampleRate);
m_ctcssNco.setFreq(NFMModSettings::getCTCSSFreq(m_settings.m_ctcssIndex), sampleRate);
m_toneNco.setFreq(m_settings.m_toneFrequency, (float) sampleRate);
m_ctcssNco.setFreq(NFMModSettings::getCTCSSFreq(m_settings.m_ctcssIndex), (float) sampleRate);
m_dcsMod.setSampleRate(sampleRate);
m_cwKeyer.setSampleRate(sampleRate);
m_cwKeyer.reset();
m_preemphasisFilter.configure(m_preemphasis*sampleRate);
m_audioCompressor.m_rate = sampleRate;
if (m_cwKeyer)
{
m_cwKeyer->setSampleRate(sampleRate);
m_cwKeyer->reset();
}
m_preemphasisFilter.configure(m_preemphasis * (float) sampleRate);
m_audioCompressor.m_rate = (float) sampleRate;
m_audioCompressor.initState();
m_audioSampleRate = sampleRate;
applyFeedbackAudioSampleRate(m_feedbackAudioSampleRate);
@ -393,7 +387,7 @@ void NFMModSource::applyAudioSampleRate(int sampleRate)
QList<ObjectPipe*> pipes;
MainCore::instance()->getMessagePipes().getMessagePipes(m_channel, "reportdemod", pipes);
if (pipes.size() > 0)
if (!pipes.empty())
{
for (const auto& pipe : pipes)
{
@ -417,7 +411,7 @@ void NFMModSource::applyFeedbackAudioSampleRate(int sampleRate)
m_feedbackInterpolatorDistanceRemain = 0;
m_feedbackInterpolatorConsumed = false;
m_feedbackInterpolatorDistance = (Real) sampleRate / (Real) m_audioSampleRate;
Real cutoff = std::min(sampleRate, m_audioSampleRate) / 2.2f;
Real cutoff = (float) std::min(sampleRate, m_audioSampleRate) / 2.2f;
m_feedbackInterpolator.create(48, sampleRate, cutoff, 3.0);
m_feedbackAudioSampleRate = sampleRate;
}
@ -433,11 +427,11 @@ void NFMModSource::applySettings(const NFMModSettings& settings, bool force)
}
if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || force) {
m_toneNco.setFreq(settings.m_toneFrequency, m_audioSampleRate);
m_toneNco.setFreq(settings.m_toneFrequency, (float) m_audioSampleRate);
}
if ((settings.m_ctcssIndex != m_settings.m_ctcssIndex) || force) {
m_ctcssNco.setFreq(NFMModSettings::getCTCSSFreq(settings.m_ctcssIndex), m_audioSampleRate);
m_ctcssNco.setFreq(NFMModSettings::getCTCSSFreq(settings.m_ctcssIndex), (float) m_audioSampleRate);
}
if ((settings.m_dcsCode != m_settings.m_dcsCode) || force) {
@ -469,7 +463,7 @@ void NFMModSource::applyChannelSettings(int channelSampleRate, int channelFreque
if ((channelFrequencyOffset != m_channelFrequencyOffset)
|| (channelSampleRate != m_channelSampleRate) || force)
{
m_carrierNco.setFreq(channelFrequencyOffset, channelSampleRate);
m_carrierNco.setFreq((float) channelFrequencyOffset, (float) channelSampleRate);
}
if ((channelSampleRate != m_channelSampleRate) || force)
@ -486,7 +480,6 @@ void NFMModSource::applyChannelSettings(int channelSampleRate, int channelFreque
void NFMModSource::handleAudio()
{
QMutexLocker mlock(&m_mutex);
unsigned int nbRead;
while ((nbRead = m_audioFifo.read(reinterpret_cast<quint8*>(&m_audioReadBuffer[m_audioReadBufferFill]), 4096)) != 0)

View File

@ -33,7 +33,6 @@
#include "dsp/firfilter.h"
#include "dsp/filterrc.h"
#include "util/movingaverage.h"
#include "dsp/cwkeyer.h"
#include "audio/audiofifo.h"
#include "audio/audiocompressorsnd.h"
@ -41,17 +40,18 @@
#include "nfmmoddcs.h"
class ChannelAPI;
class CWKeyer;
class NFMModSource : public QObject, public ChannelSampleSource
{
Q_OBJECT
public:
NFMModSource();
virtual ~NFMModSource();
~NFMModSource() final;
virtual void pull(SampleVector::iterator begin, unsigned int nbSamples);
virtual void pullOne(Sample& sample);
virtual void prefetch(unsigned int nbSamples);
void pull(SampleVector::iterator begin, unsigned int nbSamples) final;
void pullOne(Sample& sample) final;
void prefetch(unsigned int nbSamples) final;
void setInputFileStream(std::ifstream *ifstream) { m_ifstream = ifstream; }
AudioFifo *getAudioFifo() { return &m_audioFifo; }
@ -61,7 +61,8 @@ public:
int getAudioSampleRate() const { return m_audioSampleRate; }
int getFeedbackAudioSampleRate() const { return m_feedbackAudioSampleRate; }
void setChannel(ChannelAPI *channel) { m_channel = channel; }
CWKeyer& getCWKeyer() { return m_cwKeyer; }
void setCWKeyer(CWKeyer *cwKeyer) { m_cwKeyer = cwKeyer; }
CWKeyer *getCWKeyer() { return m_cwKeyer; }
double getMagSq() const { return m_magsq; }
void getLevels(qreal& rmsLevel, qreal& peakLevel, int& numSamples) const
{
@ -73,8 +74,8 @@ public:
void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = false);
private:
int m_channelSampleRate;
int m_channelFrequencyOffset;
int m_channelSampleRate = 48000;
int m_channelFrequencyOffset = 0;
NFMModSettings m_settings;
ChannelAPI *m_channel;
@ -82,7 +83,7 @@ private:
NCOF m_toneNco;
NCOF m_ctcssNco;
NFMModDCS m_dcsMod;
float m_modPhasor; //!< baseband modulator phasor
float m_modPhasor = 0.0f; //!< baseband modulator phasor
Complex m_modSample;
Interpolator m_interpolator;
@ -105,7 +106,7 @@ private:
double m_magsq;
MovingAverageUtil<double, double, 16> m_movingAverage;
int m_audioSampleRate;
int m_audioSampleRate = 48000;
AudioVector m_audioBuffer;
unsigned int m_audioBufferFill;
AudioVector m_audioReadBuffer;
@ -117,14 +118,14 @@ private:
uint m_feedbackAudioBufferFill;
AudioFifo m_feedbackAudioFifo;
quint32 m_levelCalcCount;
quint32 m_levelCalcCount = 0;
qreal m_rmsLevel;
qreal m_peakLevelOut;
Real m_peakLevel;
Real m_levelSum;
Real m_peakLevel = 0.0f;
Real m_levelSum = 0.0f;
std::ifstream *m_ifstream;
CWKeyer m_cwKeyer;
std::ifstream *m_ifstream = nullptr;
CWKeyer *m_cwKeyer = nullptr;
AudioCompressorSnd m_audioCompressor;
@ -133,11 +134,11 @@ private:
static const int m_levelNbSamples;
static const float m_preemphasis;
void processOneSample(Complex& ci);
void processOneSample(const Complex& ci);
void pullAF(Real& sample);
void pullAudio(unsigned int nbSamples);
void pushFeedback(Real sample);
void calculateLevel(Real& sample);
void calculateLevel(const Real& sample);
void modulateSample();
private slots:

View File

@ -57,20 +57,9 @@ const char* const SSBMod::m_channelId = "SSBMod";
SSBMod::SSBMod(DeviceAPI *deviceAPI) :
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSource),
m_deviceAPI(deviceAPI),
m_spectrumVis(SDR_TX_SCALEF),
m_fileSize(0),
m_recordLength(0),
m_sampleRate(48000)
m_spectrumVis(SDR_TX_SCALEF)
{
setObjectName(m_channelId);
m_thread = new QThread(this);
m_basebandSource = new SSBModBaseband();
m_basebandSource->setSpectrumSink(&m_spectrumVis);
m_basebandSource->setInputFileStream(&m_ifstream);
m_basebandSource->setChannel(this);
m_basebandSource->moveToThread(m_thread);
applySettings(m_settings, true);
m_deviceAPI->addChannelSource(this);
@ -96,8 +85,8 @@ SSBMod::~SSBMod()
delete m_networkManager;
m_deviceAPI->removeChannelSourceAPI(this);
m_deviceAPI->removeChannelSource(this);
delete m_basebandSource;
delete m_thread;
SSBMod::stop();
}
void SSBMod::setDeviceAPI(DeviceAPI *deviceAPI)
@ -114,21 +103,62 @@ void SSBMod::setDeviceAPI(DeviceAPI *deviceAPI)
void SSBMod::start()
{
if (m_running) {
return;
}
qDebug("SSBMod::start");
m_thread = new QThread(this);
m_basebandSource = new SSBModBaseband();
m_basebandSource->setSpectrumSink(&m_spectrumVis);
m_basebandSource->setInputFileStream(&m_ifstream);
m_basebandSource->setChannel(this);
m_basebandSource->reset();
m_basebandSource->setCWKeyer(&m_cwKeyer);
m_basebandSource->moveToThread(m_thread);
QObject::connect(
m_thread,
&QThread::finished,
m_basebandSource,
&QObject::deleteLater
);
QObject::connect(
m_thread,
&QThread::finished,
m_thread,
&QThread::deleteLater
);
m_thread->start();
SSBModBaseband::MsgConfigureSSBModBaseband *msg = SSBModBaseband::MsgConfigureSSBModBaseband::create(m_settings, true);
m_basebandSource->getInputMessageQueue()->push(msg);
if (m_levelMeter) {
connect(m_basebandSource, SIGNAL(levelChanged(qreal, qreal, int)), m_levelMeter, SLOT(levelChanged(qreal, qreal, int)));
}
m_running = true;
}
void SSBMod::stop()
{
if (!m_running) {
return;
}
qDebug("SSBMod::stop");
m_running = false;
m_thread->exit();
m_thread->wait();
}
void SSBMod::pull(SampleVector::iterator& begin, unsigned int nbSamples)
{
if (m_running) {
m_basebandSource->pull(begin, nbSamples);
}
}
void SSBMod::setCenterFrequency(qint64 frequency)
@ -148,7 +178,7 @@ bool SSBMod::handleMessage(const Message& cmd)
{
if (MsgConfigureSSBMod::match(cmd))
{
MsgConfigureSSBMod& cfg = (MsgConfigureSSBMod&) cmd;
auto& cfg = (const MsgConfigureSSBMod&) cmd;
qDebug() << "SSBMod::handleMessage: MsgConfigureSSBMod";
applySettings(cfg.getSettings(), cfg.getForce());
@ -157,14 +187,14 @@ bool SSBMod::handleMessage(const Message& cmd)
}
else if (MsgConfigureFileSourceName::match(cmd))
{
MsgConfigureFileSourceName& conf = (MsgConfigureFileSourceName&) cmd;
auto& conf = (const MsgConfigureFileSourceName&) cmd;
m_fileName = conf.getFileName();
openFileStream();
return true;
}
else if (MsgConfigureFileSourceSeek::match(cmd))
{
MsgConfigureFileSourceSeek& conf = (MsgConfigureFileSourceSeek&) cmd;
auto& conf = (const MsgConfigureFileSourceSeek&) cmd;
int seekPercentage = conf.getPercentage();
seekFileStream(seekPercentage);
@ -182,8 +212,7 @@ bool SSBMod::handleMessage(const Message& cmd)
if (getMessageQueueToGUI())
{
MsgReportFileSourceStreamTiming *report;
report = MsgReportFileSourceStreamTiming::create(samplesCount);
auto *report = MsgReportFileSourceStreamTiming::create(samplesCount);
getMessageQueueToGUI()->push(report);
}
@ -191,7 +220,7 @@ bool SSBMod::handleMessage(const Message& cmd)
}
else if (CWKeyer::MsgConfigureCWKeyer::match(cmd))
{
const CWKeyer::MsgConfigureCWKeyer& cfg = (CWKeyer::MsgConfigureCWKeyer&) cmd;
auto& cfg = (const CWKeyer::MsgConfigureCWKeyer&) cmd;
if (m_settings.m_useReverseAPI) {
webapiReverseSendCWSettings(cfg.getSettings());
@ -201,11 +230,14 @@ bool SSBMod::handleMessage(const Message& cmd)
}
else if (DSPSignalNotification::match(cmd))
{
auto& notif = (const DSPSignalNotification&) cmd;
// Forward to the source
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy
if (m_running)
{
auto* rep = new DSPSignalNotification(notif); // make a copy
qDebug() << "SSBMod::handleMessage: DSPSignalNotification";
m_basebandSource->getInputMessageQueue()->push(rep);
}
// Forward to GUI if any
if (getMessageQueueToGUI()) {
getMessageQueueToGUI()->push(new DSPSignalNotification(notif));
@ -237,7 +269,7 @@ void SSBMod::openFileStream()
m_ifstream.seekg(0,std::ios_base::beg);
m_sampleRate = 48000; // fixed rate
m_recordLength = m_fileSize / (sizeof(Real) * m_sampleRate);
m_recordLength = (quint32) (m_fileSize / (sizeof(Real) * m_sampleRate));
qDebug() << "SSBMod::openFileStream: " << m_fileName.toStdString().c_str()
<< " fileSize: " << m_fileSize << "bytes"
@ -360,8 +392,11 @@ void SSBMod::applySettings(const SSBModSettings& settings, bool force)
m_spectrumVis.getInputMessageQueue()->push(msg);
}
if (m_running)
{
SSBModBaseband::MsgConfigureSSBModBaseband *msg = SSBModBaseband::MsgConfigureSSBModBaseband::create(settings, force);
m_basebandSource->getInputMessageQueue()->push(msg);
}
if (settings.m_useReverseAPI)
{
@ -376,7 +411,7 @@ void SSBMod::applySettings(const SSBModSettings& settings, bool force)
QList<ObjectPipe*> pipes;
MainCore::instance()->getMessagePipes().getMessagePipes(this, "settings", pipes);
if (pipes.size() > 0) {
if (!pipes.empty()) {
sendChannelSettings(pipes, reverseAPIKeys, settings, force);
}
@ -408,12 +443,12 @@ bool SSBMod::deserialize(const QByteArray& data)
}
}
void SSBMod::sendSampleRateToDemodAnalyzer()
void SSBMod::sendSampleRateToDemodAnalyzer() const
{
QList<ObjectPipe*> pipes;
MainCore::instance()->getMessagePipes().getMessagePipes(this, "reportdemod", pipes);
if (pipes.size() > 0)
if (!pipes.empty())
{
for (const auto& pipe : pipes)
{
@ -437,7 +472,7 @@ int SSBMod::webapiSettingsGet(
webapiFormatChannelSettings(response, m_settings);
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = response.getSsbModSettings()->getCwKeyer();
const CWKeyerSettings& cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
const CWKeyerSettings& cwKeyerSettings = m_cwKeyer.getSettings();
CWKeyer::webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
return 200;
@ -465,11 +500,11 @@ int SSBMod::webapiSettingsPutPatch(
if (channelSettingsKeys.contains("cwKeyer"))
{
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = response.getSsbModSettings()->getCwKeyer();
CWKeyerSettings cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
CWKeyerSettings cwKeyerSettings = m_cwKeyer.getSettings();
CWKeyer::webapiSettingsPutPatch(channelSettingsKeys, cwKeyerSettings, apiCwKeyerSettings);
CWKeyer::MsgConfigureCWKeyer *msgCwKeyer = CWKeyer::MsgConfigureCWKeyer::create(cwKeyerSettings, force);
m_basebandSource->getCWKeyer().getInputMessageQueue()->push(msgCwKeyer);
m_cwKeyer.getInputMessageQueue()->push(msgCwKeyer);
if (m_guiMessageQueue) // forward to GUI if any
{
@ -564,13 +599,13 @@ void SSBMod::webapiUpdateChannelSettings(
settings.m_reverseAPIAddress = *response.getSsbModSettings()->getReverseApiAddress();
}
if (channelSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getSsbModSettings()->getReverseApiPort();
settings.m_reverseAPIPort = (uint16_t) response.getSsbModSettings()->getReverseApiPort();
}
if (channelSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getSsbModSettings()->getReverseApiDeviceIndex();
settings.m_reverseAPIDeviceIndex = (uint16_t) response.getSsbModSettings()->getReverseApiDeviceIndex();
}
if (channelSettingsKeys.contains("reverseAPIChannelIndex")) {
settings.m_reverseAPIChannelIndex = response.getSsbModSettings()->getReverseApiChannelIndex();
settings.m_reverseAPIChannelIndex = (uint16_t) response.getSsbModSettings()->getReverseApiChannelIndex();
}
if (settings.m_spectrumGUI && channelSettingsKeys.contains("spectrumConfig")) {
settings.m_spectrumGUI->updateFrom(channelSettingsKeys, response.getSsbModSettings()->getSpectrumConfig());
@ -651,7 +686,7 @@ void SSBMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respon
}
else
{
SWGSDRangel::SWGGLSpectrum *swgGLSpectrum = new SWGSDRangel::SWGGLSpectrum();
auto *swgGLSpectrum = new SWGSDRangel::SWGGLSpectrum();
settings.m_spectrumGUI->formatTo(swgGLSpectrum);
response.getSsbModSettings()->setSpectrumConfig(swgGLSpectrum);
}
@ -665,7 +700,7 @@ void SSBMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respon
}
else
{
SWGSDRangel::SWGChannelMarker *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
auto *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
settings.m_channelMarker->formatTo(swgChannelMarker);
response.getSsbModSettings()->setChannelMarker(swgChannelMarker);
}
@ -679,23 +714,27 @@ void SSBMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respon
}
else
{
SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState();
auto *swgRollupState = new SWGSDRangel::SWGRollupState();
settings.m_rollupState->formatTo(swgRollupState);
response.getSsbModSettings()->setRollupState(swgRollupState);
}
}
}
void SSBMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
void SSBMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) const
{
response.getSsbModReport()->setChannelPowerDb(CalcDb::dbPower(getMagSq()));
response.getSsbModReport()->setChannelPowerDb((float) CalcDb::dbPower(getMagSq()));
if (m_running)
{
response.getSsbModReport()->setAudioSampleRate(m_basebandSource->getAudioSampleRate());
response.getSsbModReport()->setChannelSampleRate(m_basebandSource->getChannelSampleRate());
}
}
void SSBMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const SSBModSettings& settings, bool force)
void SSBMod::webapiReverseSendSettings(const QList<QString>& channelSettingsKeys, const SSBModSettings& settings, bool force)
{
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
auto *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
webapiFormatChannelSettings(channelSettingsKeys, swgChannelSettings, settings, force);
QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
@ -706,8 +745,8 @@ void SSBMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, cons
m_networkRequest.setUrl(QUrl(channelSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgChannelSettings->asJson().toUtf8());
buffer->seek(0);
@ -720,7 +759,7 @@ void SSBMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, cons
void SSBMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
{
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
auto *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
swgChannelSettings->setDirection(1); // single source (Tx)
swgChannelSettings->setChannelType(new QString("SSBMod"));
swgChannelSettings->setSsbModSettings(new SWGSDRangel::SWGSSBModSettings());
@ -728,7 +767,7 @@ void SSBMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
swgSSBModSettings->setCwKeyer(new SWGSDRangel::SWGCWKeyerSettings());
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = swgSSBModSettings->getCwKeyer();
m_basebandSource->getCWKeyer().webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
CWKeyer::webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
.arg(m_settings.m_reverseAPIAddress)
@ -738,8 +777,8 @@ void SSBMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
m_networkRequest.setUrl(QUrl(channelSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgChannelSettings->asJson().toUtf8());
buffer->seek(0);
@ -752,9 +791,9 @@ void SSBMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
void SSBMod::sendChannelSettings(
const QList<ObjectPipe*>& pipes,
QList<QString>& channelSettingsKeys,
const QList<QString>& channelSettingsKeys,
const SSBModSettings& settings,
bool force)
bool force) const
{
for (const auto& pipe : pipes)
{
@ -762,7 +801,7 @@ void SSBMod::sendChannelSettings(
if (messageQueue)
{
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
auto *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
webapiFormatChannelSettings(channelSettingsKeys, swgChannelSettings, settings, force);
MainCore::MsgChannelSettings *msg = MainCore::MsgChannelSettings::create(
this,
@ -776,11 +815,11 @@ void SSBMod::sendChannelSettings(
}
void SSBMod::webapiFormatChannelSettings(
QList<QString>& channelSettingsKeys,
const QList<QString>& channelSettingsKeys,
SWGSDRangel::SWGChannelSettings *swgChannelSettings,
const SSBModSettings& settings,
bool force
)
) const
{
swgChannelSettings->setDirection(1); // single source (Tx)
swgChannelSettings->setOriginatorChannelIndex(getIndexInDeviceSet());
@ -854,35 +893,35 @@ void SSBMod::webapiFormatChannelSettings(
if (settings.m_spectrumGUI && (channelSettingsKeys.contains("spectrunConfig") || force))
{
SWGSDRangel::SWGGLSpectrum *swgGLSpectrum = new SWGSDRangel::SWGGLSpectrum();
auto *swgGLSpectrum = new SWGSDRangel::SWGGLSpectrum();
settings.m_spectrumGUI->formatTo(swgGLSpectrum);
swgSSBModSettings->setSpectrumConfig(swgGLSpectrum);
}
if (settings.m_channelMarker && (channelSettingsKeys.contains("channelMarker") || force))
{
SWGSDRangel::SWGChannelMarker *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
auto *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
settings.m_channelMarker->formatTo(swgChannelMarker);
swgSSBModSettings->setChannelMarker(swgChannelMarker);
}
if (settings.m_rollupState && (channelSettingsKeys.contains("rollupState") || force))
{
SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState();
auto *swgRollupState = new SWGSDRangel::SWGRollupState();
settings.m_rollupState->formatTo(swgRollupState);
swgSSBModSettings->setRollupState(swgRollupState);
}
if (force)
{
const CWKeyerSettings& cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
const CWKeyerSettings& cwKeyerSettings = m_cwKeyer.getSettings();
swgSSBModSettings->setCwKeyer(new SWGSDRangel::SWGCWKeyerSettings());
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = swgSSBModSettings->getCwKeyer();
m_basebandSource->getCWKeyer().webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
CWKeyer::webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
}
}
void SSBMod::networkManagerFinished(QNetworkReply *reply)
void SSBMod::networkManagerFinished(QNetworkReply *reply) const
{
QNetworkReply::NetworkError replyError = reply->error();
@ -905,27 +944,34 @@ void SSBMod::networkManagerFinished(QNetworkReply *reply)
double SSBMod::getMagSq() const
{
if (m_running) {
return m_basebandSource->getMagSq();
}
return 0;
}
CWKeyer *SSBMod::getCWKeyer()
{
return &m_basebandSource->getCWKeyer();
}
void SSBMod::setLevelMeter(QObject *levelMeter)
{
connect(m_basebandSource, SIGNAL(levelChanged(qreal, qreal, int)), levelMeter, SLOT(levelChanged(qreal, qreal, int)));
return &m_cwKeyer;
}
int SSBMod::getAudioSampleRate() const
{
if (m_running) {
return m_basebandSource->getAudioSampleRate();
}
return 0;
}
int SSBMod::getFeedbackAudioSampleRate() const
{
if (m_running) {
return m_basebandSource->getFeedbackAudioSampleRate();
}
return 0;
}
uint32_t SSBMod::getNumberOfDeviceStreams() const

View File

@ -29,6 +29,7 @@
#include "dsp/basebandsamplesource.h"
#include "dsp/spectrumvis.h"
#include "dsp/cwkeyer.h"
#include "channel/channelapi.h"
#include "util/message.h"
@ -82,7 +83,7 @@ public:
private:
QString m_fileName;
MsgConfigureFileSourceName(const QString& fileName) :
explicit MsgConfigureFileSourceName(const QString& fileName) :
Message(),
m_fileName(fileName)
{ }
@ -100,10 +101,10 @@ public:
return new MsgConfigureFileSourceSeek(seekPercentage);
}
protected:
private:
int m_seekPercentage; //!< percentage of seek position from the beginning 0..100
MsgConfigureFileSourceSeek(int seekPercentage) :
explicit MsgConfigureFileSourceSeek(int seekPercentage) :
Message(),
m_seekPercentage(seekPercentage)
{ }
@ -138,10 +139,10 @@ public:
return new MsgReportFileSourceStreamTiming(samplesCount);
}
protected:
private:
std::size_t m_samplesCount;
MsgReportFileSourceStreamTiming(std::size_t samplesCount) :
explicit MsgReportFileSourceStreamTiming(std::size_t samplesCount) :
Message(),
m_samplesCount(samplesCount)
{ }
@ -160,7 +161,7 @@ public:
return new MsgReportFileSourceStreamData(sampleRate, recordLength);
}
protected:
private:
int m_sampleRate;
quint32 m_recordLength;
@ -174,55 +175,55 @@ public:
//=================================================================
SSBMod(DeviceAPI *deviceAPI);
virtual ~SSBMod();
virtual void destroy() { delete this; }
virtual void setDeviceAPI(DeviceAPI *deviceAPI);
virtual DeviceAPI *getDeviceAPI() { return m_deviceAPI; }
explicit SSBMod(DeviceAPI *deviceAPI);
~SSBMod() final;
void destroy() final { delete this; }
void setDeviceAPI(DeviceAPI *deviceAPI) final;
DeviceAPI *getDeviceAPI() final { return m_deviceAPI; }
virtual void start();
virtual void stop();
virtual void pull(SampleVector::iterator& begin, unsigned int nbSamples);
virtual void pushMessage(Message *msg) { m_inputMessageQueue.push(msg); }
virtual QString getSourceName() { return objectName(); }
void start() final;
void stop() final;
void pull(SampleVector::iterator& begin, unsigned int nbSamples) final;
void pushMessage(Message *msg) final { m_inputMessageQueue.push(msg); }
QString getSourceName() final { return objectName(); }
virtual void getIdentifier(QString& id) { id = objectName(); }
virtual QString getIdentifier() const { return objectName(); }
virtual void getTitle(QString& title) { title = m_settings.m_title; }
virtual qint64 getCenterFrequency() const { return m_settings.m_inputFrequencyOffset; }
virtual void setCenterFrequency(qint64 frequency);
void getIdentifier(QString& id) final { id = objectName(); }
QString getIdentifier() const final { return objectName(); }
void getTitle(QString& title) final { title = m_settings.m_title; }
qint64 getCenterFrequency() const final { return m_settings.m_inputFrequencyOffset; }
void setCenterFrequency(qint64 frequency) final;
virtual QByteArray serialize() const;
virtual bool deserialize(const QByteArray& data);
QByteArray serialize() const final;
bool deserialize(const QByteArray& data) final;
virtual int getNbSinkStreams() const { return 1; }
virtual int getNbSourceStreams() const { return 0; }
virtual int getStreamIndex() const { return m_settings.m_streamIndex; }
int getNbSinkStreams() const final { return 1; }
int getNbSourceStreams() const final { return 0; }
int getStreamIndex() const final { return m_settings.m_streamIndex; }
virtual qint64 getStreamCenterFrequency(int streamIndex, bool sinkElseSource) const
qint64 getStreamCenterFrequency(int streamIndex, bool sinkElseSource) const final
{
(void) streamIndex;
(void) sinkElseSource;
return m_settings.m_inputFrequencyOffset;
}
virtual int webapiSettingsGet(
int webapiSettingsGet(
SWGSDRangel::SWGChannelSettings& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiWorkspaceGet(
int webapiWorkspaceGet(
SWGSDRangel::SWGWorkspaceInfo& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiSettingsPutPatch(
int webapiSettingsPutPatch(
bool force,
const QStringList& channelSettingsKeys,
SWGSDRangel::SWGChannelSettings& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiReportGet(
int webapiReportGet(
SWGSDRangel::SWGChannelReport& response,
QString& errorMessage);
QString& errorMessage) final;
static void webapiFormatChannelSettings(
SWGSDRangel::SWGChannelSettings& response,
@ -236,7 +237,7 @@ public:
SpectrumVis *getSpectrumVis() { return &m_spectrumVis; }
double getMagSq() const;
CWKeyer *getCWKeyer();
void setLevelMeter(QObject *levelMeter);
void setLevelMeter(QObject *levelMeter) { m_levelMeter = levelMeter; }
int getAudioSampleRate() const;
int getFeedbackAudioSampleRate() const;
uint32_t getNumberOfDeviceStreams() const;
@ -252,6 +253,7 @@ private:
DeviceAPI* m_deviceAPI;
QThread *m_thread;
bool m_running = false;
SSBModBaseband* m_basebandSource;
SSBModSettings m_settings;
SpectrumVis m_spectrumVis;
@ -261,36 +263,38 @@ private:
std::ifstream m_ifstream;
QString m_fileName;
quint64 m_fileSize; //!< raw file size (bytes)
quint32 m_recordLength; //!< record length in seconds computed from file size
int m_sampleRate;
quint64 m_fileSize = 0; //!< raw file size (bytes)
quint32 m_recordLength = 0; //!< record length in seconds computed from file size
int m_sampleRate = 48000;
QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
CWKeyer m_cwKeyer;
QObject *m_levelMeter;
virtual bool handleMessage(const Message& cmd);
bool handleMessage(const Message& cmd) final;
void applySettings(const SSBModSettings& settings, bool force = false);
void sendSampleRateToDemodAnalyzer();
void sendSampleRateToDemodAnalyzer() const;
void openFileStream();
void seekFileStream(int seekPercentage);
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const SSBModSettings& settings, bool force);
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) const;
void webapiReverseSendSettings(const QList<QString>& channelSettingsKeys, const SSBModSettings& settings, bool force);
void webapiReverseSendCWSettings(const CWKeyerSettings& settings);
void sendChannelSettings(
const QList<ObjectPipe*>& pipes,
QList<QString>& channelSettingsKeys,
const QList<QString>& channelSettingsKeys,
const SSBModSettings& settings,
bool force
);
) const;
void webapiFormatChannelSettings(
QList<QString>& channelSettingsKeys,
const QList<QString>& channelSettingsKeys,
SWGSDRangel::SWGChannelSettings *swgChannelSettings,
const SSBModSettings& settings,
bool force
);
) const;
private slots:
void networkManagerFinished(QNetworkReply *reply);
void networkManagerFinished(QNetworkReply *reply) const;
};

View File

@ -171,8 +171,8 @@ bool SSBModBaseband::handleMessage(const Message& cmd)
QMutexLocker mutexLocker(&m_mutex);
const CWKeyer::MsgConfigureCWKeyer& cfg = (CWKeyer::MsgConfigureCWKeyer&) cmd;
CWKeyer::MsgConfigureCWKeyer *notif = new CWKeyer::MsgConfigureCWKeyer(cfg);
CWKeyer& cwKeyer = m_source.getCWKeyer();
cwKeyer.getInputMessageQueue()->push(notif);
CWKeyer *cwKeyer = m_source.getCWKeyer();
cwKeyer->getInputMessageQueue()->push(notif);
return true;
}

View File

@ -65,7 +65,7 @@ public:
void reset();
void pull(const SampleVector::iterator& begin, unsigned int nbSamples);
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
CWKeyer& getCWKeyer() { return m_source.getCWKeyer(); }
void setCWKeyer(CWKeyer *cwKeyer) { m_source.setCWKeyer(cwKeyer); }
double getMagSq() const { return m_source.getMagSq(); }
int getAudioSampleRate() const { return m_source.getAudioSampleRate(); }
int getFeedbackAudioSampleRate() const { return m_source.getFeedbackAudioSampleRate(); }

View File

@ -30,21 +30,13 @@ const int SSBModSource::m_ssbFftLen = 1024;
const int SSBModSource::m_levelNbSamples = 480; // every 10ms
SSBModSource::SSBModSource() :
m_channelSampleRate(48000),
m_channelFrequencyOffset(0),
m_spectrumSink(nullptr),
m_audioSampleRate(48000),
m_audioFifo(12000),
m_feedbackAudioFifo(12000),
m_levelCalcCount(0),
m_peakLevel(0.0f),
m_levelSum(0.0f),
m_ifstream(nullptr)
m_feedbackAudioFifo(12000)
{
m_audioFifo.setLabel("SSBModSource.m_audioFifo");
m_feedbackAudioFifo.setLabel("SSBModSource.m_feedbackAudioFifo");
m_SSBFilter = new fftfilt(m_settings.m_lowCutoff / m_audioSampleRate, m_settings.m_bandwidth / m_audioSampleRate, m_ssbFftLen);
m_DSBFilter = new fftfilt((2.0f * m_settings.m_bandwidth) / m_audioSampleRate, 2 * m_ssbFftLen);
m_SSBFilter = new fftfilt(m_settings.m_lowCutoff / (float) m_audioSampleRate, m_settings.m_bandwidth / (float) m_audioSampleRate, m_ssbFftLen);
m_DSBFilter = new fftfilt((2.0f * m_settings.m_bandwidth) / (float) m_audioSampleRate, 2 * m_ssbFftLen);
m_SSBFilterBuffer = new Complex[m_ssbFftLen>>1]; // filter returns data exactly half of its size
m_DSBFilterBuffer = new Complex[m_ssbFftLen];
std::fill(m_SSBFilterBuffer, m_SSBFilterBuffer+(m_ssbFftLen>>1), Complex{0,0});
@ -67,18 +59,15 @@ SSBModSource::SSBModSource() :
m_sumCount = 0;
m_magsq = 0.0;
m_toneNco.setFreq(1000.0, m_audioSampleRate);
m_cwKeyer.setSampleRate(m_audioSampleRate);
m_cwKeyer.reset();
m_toneNco.setFreq(1000.0, (float) m_audioSampleRate);
m_audioCompressor.initSimple(
m_audioSampleRate,
m_settings.m_cmpPreGainDB, // pregain (dB)
m_settings.m_cmpThresholdDB, // threshold (dB)
(float) m_settings.m_cmpPreGainDB, // pregain (dB)
(float) m_settings.m_cmpThresholdDB, // threshold (dB)
20, // knee (dB)
12, // ratio (dB)
0.003, // attack (s)
0.003f,// attack (s)
0.25 // release (s)
);
@ -142,7 +131,7 @@ void SSBModSource::pullOne(Sample& sample)
void SSBModSource::prefetch(unsigned int nbSamples)
{
unsigned int nbSamplesAudio = nbSamples * ((Real) m_audioSampleRate / (Real) m_channelSampleRate);
unsigned int nbSamplesAudio = (nbSamples * (unsigned int) ((Real) m_audioSampleRate / (Real) m_channelSampleRate));
pullAudio(nbSamplesAudio);
}
@ -176,13 +165,16 @@ void SSBModSource::modulateSample()
if (m_settings.m_audioBinaural)
{
m_demodBuffer[m_demodBufferFill++] = m_modSample.real() * std::numeric_limits<int16_t>::max();
m_demodBuffer[m_demodBufferFill++] = m_modSample.imag() * std::numeric_limits<int16_t>::max();
m_demodBuffer[m_demodBufferFill] = (qint16) (m_modSample.real() * std::numeric_limits<int16_t>::max());
m_demodBufferFill++;
m_demodBuffer[m_demodBufferFill] = (qint16) (m_modSample.imag() * std::numeric_limits<int16_t>::max());
m_demodBufferFill++;
}
else
{
// take projection on real axis
m_demodBuffer[m_demodBufferFill++] = m_modSample.real() * std::numeric_limits<int16_t>::max();
m_demodBuffer[m_demodBufferFill] = (qint16) (m_modSample.real() * std::numeric_limits<int16_t>::max());
m_demodBufferFill++;
}
if (m_demodBufferFill >= m_demodBuffer.size())
@ -190,13 +182,11 @@ void SSBModSource::modulateSample()
QList<ObjectPipe*> dataPipes;
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
if (dataPipes.size() > 0)
if (!dataPipes.empty())
{
QList<ObjectPipe*>::iterator it = dataPipes.begin();
for (; it != dataPipes.end(); ++it)
for (auto& dataPipe : dataPipes)
{
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
DataFifo *fifo = qobject_cast<DataFifo*>(dataPipe->m_element);
if (fifo)
{
@ -227,14 +217,14 @@ void SSBModSource::pullAF(Complex& sample)
int n_out = 0;
int decim = 1<<(m_settings.m_spanLog2 - 1);
unsigned char decim_mask = decim - 1; // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
auto decim_mask = (unsigned char) ((decim - 1) & 0xFF); // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
switch (m_settings.m_modAFInput)
{
case SSBModSettings::SSBModInputTone:
if (m_settings.m_dsb)
{
Real t = m_toneNco.next()/1.25;
Real t = m_toneNco.next()/1.25f;
sample.real(t);
sample.imag(t);
}
@ -248,22 +238,13 @@ void SSBModSource::pullAF(Complex& sample)
}
break;
case SSBModSettings::SSBModInputFile:
// Monaural (mono):
// sox f4exb_call.wav --encoding float --endian little f4exb_call.raw
// ffplay -f f32le -ar 48k -ac 1 f4exb_call.raw
// Binaural (stereo):
// sox f4exb_call.wav --encoding float --endian little f4exb_call.raw
// ffplay -f f32le -ar 48k -ac 2 f4exb_call.raw
if (m_ifstream && m_ifstream->is_open())
{
if (m_ifstream->eof())
{
if (m_settings.m_playLoop)
if (m_ifstream->eof() && m_settings.m_playLoop)
{
m_ifstream->clear();
m_ifstream->seekg(0, std::ios::beg);
}
}
if (m_ifstream->eof())
{
@ -330,8 +311,8 @@ void SSBModSource::pullAF(Complex& sample)
{
if (m_settings.m_agc)
{
float sample = (m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f;
ci.real(clamp<float>(m_audioCompressor.compress(sample), -1.0f, 1.0f));
float xsample = (m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f;
ci.real(clamp<float>(m_audioCompressor.compress(xsample), -1.0f, 1.0f));
ci.imag(0.0f);
ci *= m_settings.m_volumeFactor;
}
@ -349,16 +330,20 @@ void SSBModSource::pullAF(Complex& sample)
else
{
qDebug("SSBModSource::pullAF: starve audio samples: size: %lu", m_audioBuffer.size());
m_audioBufferFill = m_audioBuffer.size() - 1;
m_audioBufferFill = (unsigned int) (m_audioBuffer.size() - 1);
}
break;
case SSBModSettings::SSBModInputCWTone:
if (!m_cwKeyer) {
break;
}
Real fadeFactor;
if (m_cwKeyer.getSample())
if (m_cwKeyer->getSample())
{
m_cwKeyer.getCWSmoother().getFadeSample(true, fadeFactor);
m_cwKeyer->getCWSmoother().getFadeSample(true, fadeFactor);
if (m_settings.m_dsb)
{
@ -377,11 +362,11 @@ void SSBModSource::pullAF(Complex& sample)
}
else
{
if (m_cwKeyer.getCWSmoother().getFadeSample(false, fadeFactor))
if (m_cwKeyer->getCWSmoother().getFadeSample(false, fadeFactor))
{
if (m_settings.m_dsb)
{
Real t = (m_toneNco.next() * fadeFactor)/1.25;
Real t = (m_toneNco.next() * fadeFactor)/1.25f;
sample.real(t);
sample.imag(t);
}
@ -403,7 +388,6 @@ void SSBModSource::pullAF(Complex& sample)
}
break;
case SSBModSettings::SSBModInputNone:
default:
sample.real(0.0f);
sample.imag(0.0f);
@ -451,16 +435,16 @@ void SSBModSource::pullAF(Complex& sample)
if (!(m_undersampleCount++ & decim_mask))
{
Real avgr = (m_sum.real() / decim) * 0.891235351562f * SDR_TX_SCALEF; //scaling at -1 dB to account for possible filter overshoot
Real avgi = (m_sum.imag() / decim) * 0.891235351562f * SDR_TX_SCALEF;
Real avgr = (m_sum.real() / (float) decim) * 0.891235351562f * SDR_TX_SCALEF; //scaling at -1 dB to account for possible filter overshoot
Real avgi = (m_sum.imag() / (float) decim) * 0.891235351562f * SDR_TX_SCALEF;
if (!m_settings.m_dsb & !m_settings.m_usb)
if (!m_settings.m_dsb && !m_settings.m_usb)
{ // invert spectrum for LSB
m_sampleBuffer.push_back(Sample(avgi, avgr));
m_sampleBuffer.push_back(Sample((FixReal) avgi, (FixReal) avgr));
}
else
{
m_sampleBuffer.push_back(Sample(avgr, avgi));
m_sampleBuffer.push_back(Sample((FixReal) avgr, (FixReal)avgi));
}
m_sum.real(0.0);
@ -476,16 +460,16 @@ void SSBModSource::pullAF(Complex& sample)
if (!(m_undersampleCount++ & decim_mask))
{
Real avgr = (m_sum.real() / decim) * 0.891235351562f * SDR_TX_SCALEF; //scaling at -1 dB to account for possible filter overshoot
Real avgi = (m_sum.imag() / decim) * 0.891235351562f * SDR_TX_SCALEF;
Real avgr = (m_sum.real() / (float) decim) * 0.891235351562f * SDR_TX_SCALEF; //scaling at -1 dB to account for possible filter overshoot
Real avgi = (m_sum.imag() / (float) decim) * 0.891235351562f * SDR_TX_SCALEF;
if (!m_settings.m_dsb & !m_settings.m_usb)
if (!m_settings.m_dsb && !m_settings.m_usb)
{ // invert spectrum for LSB
m_sampleBuffer.push_back(Sample(avgi, avgr));
m_sampleBuffer.push_back(Sample((FixReal) avgi, (FixReal) avgr));
}
else
{
m_sampleBuffer.push_back(Sample(avgr, avgi));
m_sampleBuffer.push_back(Sample((FixReal) avgr, (FixReal) avgi));
}
m_sum.real(0.0);
@ -536,18 +520,18 @@ void SSBModSource::pushFeedback(Complex c)
}
}
void SSBModSource::processOneSample(Complex& ci)
void SSBModSource::processOneSample(const Complex& ci)
{
if (m_settings.m_modAFInput == SSBModSettings::SSBModInputCWTone) // minimize latency for CW
{
m_feedbackAudioBuffer[0].l = ci.real();
m_feedbackAudioBuffer[0].r = ci.imag();
m_feedbackAudioBuffer[0].l = (qint16) ci.real();
m_feedbackAudioBuffer[0].r = (qint16) ci.imag();
m_feedbackAudioFifo.writeOne((const quint8*) &m_feedbackAudioBuffer[0]);
}
else
{
m_feedbackAudioBuffer[m_feedbackAudioBufferFill].l = ci.real();
m_feedbackAudioBuffer[m_feedbackAudioBufferFill].r = ci.imag();
m_feedbackAudioBuffer[m_feedbackAudioBufferFill].l = (qint16) ci.real();
m_feedbackAudioBuffer[m_feedbackAudioBufferFill].r = (qint16) ci.imag();
++m_feedbackAudioBufferFill;
if (m_feedbackAudioBufferFill >= m_feedbackAudioBuffer.size())
@ -566,9 +550,9 @@ void SSBModSource::processOneSample(Complex& ci)
}
}
void SSBModSource::calculateLevel(Complex& sample)
void SSBModSource::calculateLevel(const Complex& sample)
{
Real t = sample.real(); // TODO: possibly adjust depending on sample type
Real t = sample.real();
if (m_levelCalcCount < m_levelNbSamples)
{
@ -615,18 +599,22 @@ void SSBModSource::applyAudioSampleRate(int sampleRate)
lowCutoff = band - 100.0f;
}
m_SSBFilter->create_filter(lowCutoff / sampleRate, band / sampleRate);
m_DSBFilter->create_dsb_filter((2.0f * band) / sampleRate);
m_SSBFilter->create_filter(lowCutoff / (float) sampleRate, band / (float) sampleRate);
m_DSBFilter->create_dsb_filter((2.0f * band) / (float) sampleRate);
m_settings.m_bandwidth = band;
m_settings.m_lowCutoff = lowCutoff;
m_settings.m_usb = usb;
m_toneNco.setFreq(m_settings.m_toneFrequency, sampleRate);
m_cwKeyer.setSampleRate(sampleRate);
m_cwKeyer.reset();
m_toneNco.setFreq(m_settings.m_toneFrequency, (float) sampleRate);
m_audioCompressor.m_rate = sampleRate;
if (m_cwKeyer)
{
m_cwKeyer->setSampleRate(sampleRate);
m_cwKeyer->reset();
}
m_audioCompressor.m_rate = (float) sampleRate;
m_audioCompressor.initState();
m_audioSampleRate = sampleRate;
@ -635,7 +623,7 @@ void SSBModSource::applyAudioSampleRate(int sampleRate)
QList<ObjectPipe*> pipes;
MainCore::instance()->getMessagePipes().getMessagePipes(m_channel, "reportdemod", pipes);
if (pipes.size() > 0)
if (!pipes.empty())
{
for (const auto& pipe : pipes)
{
@ -659,7 +647,7 @@ void SSBModSource::applyFeedbackAudioSampleRate(int sampleRate)
m_feedbackInterpolatorDistanceRemain = 0;
m_feedbackInterpolatorConsumed = false;
m_feedbackInterpolatorDistance = (Real) sampleRate / (Real) m_audioSampleRate;
Real cutoff = std::min(sampleRate, m_audioSampleRate) / 2.2f;
Real cutoff = (float) (std::min(sampleRate, m_audioSampleRate)) / 2.2f;
m_feedbackInterpolator.create(48, sampleRate, cutoff, 3.0);
m_feedbackAudioSampleRate = sampleRate;
}
@ -687,12 +675,12 @@ void SSBModSource::applySettings(const SSBModSettings& settings, bool force)
m_interpolatorConsumed = false;
m_interpolatorDistance = (Real) m_audioSampleRate / (Real) m_channelSampleRate;
m_interpolator.create(48, m_audioSampleRate, band, 3.0);
m_SSBFilter->create_filter(lowCutoff / m_audioSampleRate, band / m_audioSampleRate);
m_DSBFilter->create_dsb_filter((2.0f * band) / m_audioSampleRate);
m_SSBFilter->create_filter(lowCutoff / (float) m_audioSampleRate, band / (float) m_audioSampleRate);
m_DSBFilter->create_dsb_filter((2.0f * band) / (float) m_audioSampleRate);
}
if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || force) {
m_toneNco.setFreq(settings.m_toneFrequency, m_audioSampleRate);
m_toneNco.setFreq(settings.m_toneFrequency, (float) m_audioSampleRate);
}
if ((settings.m_dsb != m_settings.m_dsb) || force)
@ -723,11 +711,11 @@ void SSBModSource::applySettings(const SSBModSettings& settings, bool force)
{
m_audioCompressor.initSimple(
m_audioSampleRate,
settings.m_cmpPreGainDB, // pregain (dB)
settings.m_cmpThresholdDB, // threshold (dB)
(float) settings.m_cmpPreGainDB, // pregain (dB)
(float) settings.m_cmpThresholdDB, // threshold (dB)
20, // knee (dB)
12, // ratio (dB)
0.003, // attack (s)
0.003f,// attack (s)
0.25 // release (s)
);
}
@ -746,7 +734,7 @@ void SSBModSource::applyChannelSettings(int channelSampleRate, int channelFreque
if ((channelFrequencyOffset != m_channelFrequencyOffset)
|| (channelSampleRate != m_channelSampleRate) || force) {
m_carrierNco.setFreq(channelFrequencyOffset, channelSampleRate);
m_carrierNco.setFreq((float) channelFrequencyOffset, (float) channelSampleRate);
}
if ((channelSampleRate != m_channelSampleRate) || force)
@ -763,7 +751,6 @@ void SSBModSource::applyChannelSettings(int channelSampleRate, int channelFreque
void SSBModSource::handleAudio()
{
QMutexLocker mlock(&m_mutex);
unsigned int nbRead;
while ((nbRead = m_audioFifo.read(reinterpret_cast<quint8*>(&m_audioReadBuffer[m_audioReadBufferFill]), 4096)) != 0)

View File

@ -39,17 +39,18 @@
class ChannelAPI;
class SpectrumVis;
class CWKeyer;
class SSBModSource : public QObject, public ChannelSampleSource
{
Q_OBJECT
public:
SSBModSource();
virtual ~SSBModSource();
~SSBModSource() final;
virtual void pull(SampleVector::iterator begin, unsigned int nbSamples);
virtual void pullOne(Sample& sample);
virtual void prefetch(unsigned int nbSamples);
void pull(SampleVector::iterator begin, unsigned int nbSamples) final;
void pullOne(Sample& sample) final;
void prefetch(unsigned int nbSamples) final;
void setInputFileStream(std::ifstream *ifstream) { m_ifstream = ifstream; }
AudioFifo *getAudioFifo() { return &m_audioFifo; }
@ -59,7 +60,8 @@ public:
int getAudioSampleRate() const { return m_audioSampleRate; }
int getFeedbackAudioSampleRate() const { return m_feedbackAudioSampleRate; }
void setChannel(ChannelAPI *channel) { m_channel = channel; }
CWKeyer& getCWKeyer() { return m_cwKeyer; }
CWKeyer* getCWKeyer() { return m_cwKeyer; }
void setCWKeyer(CWKeyer *cwKeyer) { m_cwKeyer = cwKeyer; }
double getMagSq() const { return m_magsq; }
void getLevels(qreal& rmsLevel, qreal& peakLevel, int& numSamples) const
{
@ -68,12 +70,12 @@ public:
numSamples = m_levelNbSamples;
}
void applySettings(const SSBModSettings& settings, bool force = false);
void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = 0);
void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = false);
void setSpectrumSink(SpectrumVis *sampleSink) { m_spectrumSink = sampleSink; }
private:
int m_channelSampleRate;
int m_channelFrequencyOffset;
int m_channelSampleRate = 48000;
int m_channelFrequencyOffset = 0;
SSBModSettings m_settings;
ChannelAPI *m_channel;
@ -102,7 +104,7 @@ private:
int m_DSBFilterBufferIndex;
static const int m_ssbFftLen;
SpectrumVis* m_spectrumSink;
SpectrumVis* m_spectrumSink = nullptr;
SampleVector m_sampleBuffer;
fftfilt::cmplx m_sum;
@ -112,7 +114,7 @@ private:
double m_magsq;
MovingAverageUtil<double, double, 16> m_movingAverage;
int m_audioSampleRate;
int m_audioSampleRate = 48000;
AudioVector m_audioBuffer;
unsigned int m_audioBufferFill;
AudioVector m_audioReadBuffer;
@ -124,14 +126,14 @@ private:
uint m_feedbackAudioBufferFill;
AudioFifo m_feedbackAudioFifo;
quint32 m_levelCalcCount;
quint32 m_levelCalcCount = 0;
qreal m_rmsLevel;
qreal m_peakLevelOut;
Real m_peakLevel;
Real m_levelSum;
Real m_peakLevel = 0.0f;
Real m_levelSum = 0.0f;
std::ifstream *m_ifstream;
CWKeyer m_cwKeyer;
std::ifstream *m_ifstream = nullptr;
CWKeyer *m_cwKeyer = nullptr;
AudioCompressorSnd m_audioCompressor;
int m_agcStepLength;
@ -140,11 +142,11 @@ private:
static const int m_levelNbSamples;
void processOneSample(Complex& ci);
void processOneSample(const Complex& ci);
void pullAF(Complex& sample);
void pullAudio(unsigned int nbSamples);
void pushFeedback(Complex sample);
void calculateLevel(Complex& sample);
void calculateLevel(const Complex& sample);
void modulateSample();
private slots:

View File

@ -142,6 +142,12 @@ void BladeRF2MIMO::init()
bool BladeRF2MIMO::startRx()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_runningRx) {
return true;
}
qDebug("BladeRF2MIMO::startRx");
if (!m_open)
@ -150,12 +156,6 @@ bool BladeRF2MIMO::startRx()
return false;
}
QMutexLocker mutexLocker(&m_mutex);
if (m_runningRx) {
stopRx();
}
m_sourceThread = new BladeRF2MIThread(m_dev->getDev());
m_sampleMIFifo.reset();
m_sourceThread->setFifo(&m_sampleMIFifo);
@ -178,6 +178,12 @@ bool BladeRF2MIMO::startRx()
bool BladeRF2MIMO::startTx()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_runningTx) {
return true;
}
qDebug("BladeRF2MIMO::startTx");
if (!m_open)
@ -186,12 +192,6 @@ bool BladeRF2MIMO::startTx()
return false;
}
QMutexLocker mutexLocker(&m_mutex);
if (m_runningTx) {
stopTx();
}
m_sinkThread = new BladeRF2MOThread(m_dev->getDev());
m_sampleMOFifo.reset();
m_sinkThread->setFifo(&m_sampleMOFifo);
@ -213,18 +213,22 @@ bool BladeRF2MIMO::startTx()
void BladeRF2MIMO::stopRx()
{
qDebug("BladeRF2MIMO::stopRx");
QMutexLocker mutexLocker(&m_mutex);
if (!m_runningRx) {
return;
}
if (!m_sourceThread) {
return;
}
QMutexLocker mutexLocker(&m_mutex);
qDebug("BladeRF2MIMO::stopRx");
m_runningRx = false;
m_sourceThread->stopWork();
delete m_sourceThread;
m_sourceThread = nullptr;
m_runningRx = false;
for (int i = 0; i < 2; i++) {
m_dev->closeRx(i);
@ -233,18 +237,22 @@ void BladeRF2MIMO::stopRx()
void BladeRF2MIMO::stopTx()
{
qDebug("BladeRF2MIMO::stopTx");
QMutexLocker mutexLocker(&m_mutex);
if (!m_runningTx) {
return;
}
if (!m_sinkThread) {
return;
}
QMutexLocker mutexLocker(&m_mutex);
qDebug("BladeRF2MIMO::stopTx");
m_runningTx = false;
m_sinkThread->stopWork();
delete m_sinkThread;
m_sinkThread = nullptr;
m_runningTx = false;
for (int i = 0; i < 2; i++) {
m_dev->closeTx(i);

View File

@ -256,6 +256,12 @@ void LimeSDRMIMO::init()
bool LimeSDRMIMO::startRx()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_runningRx) {
return true;
}
qDebug("LimeSDRMIMO::startRx");
lms_stream_t *streams[2];
@ -265,12 +271,6 @@ bool LimeSDRMIMO::startRx()
return false;
}
QMutexLocker mutexLocker(&m_mutex);
if (m_runningRx) {
stopRx();
}
for (unsigned int channel = 0; channel < 2; channel++)
{
if (channel < m_deviceAPI->getNbSourceStreams())
@ -307,18 +307,22 @@ bool LimeSDRMIMO::startRx()
void LimeSDRMIMO::stopRx()
{
qDebug("LimeSDRMIMO::stopRx");
QMutexLocker mutexLocker(&m_mutex);
if (!m_runningRx) {
return;
}
if (!m_sourceThread) {
return;
}
QMutexLocker mutexLocker(&m_mutex);
qDebug("LimeSDRMIMO::stopRx");
m_runningRx = false;
m_sourceThread->stopWork();
delete m_sourceThread;
m_sourceThread = nullptr;
m_runningRx = false;
for (unsigned int channel = 0; channel < 2; channel++)
{
@ -330,6 +334,12 @@ void LimeSDRMIMO::stopRx()
bool LimeSDRMIMO::startTx()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_runningTx) {
return true;
}
qDebug("LimeSDRMIMO::startTx");
lms_stream_t *streams[2];
@ -339,12 +349,6 @@ bool LimeSDRMIMO::startTx()
return false;
}
QMutexLocker mutexLocker(&m_mutex);
if (m_runningTx) {
stopTx();
}
for (unsigned int channel = 0; channel < 2; channel++)
{
if (channel < m_deviceAPI->getNbSinkStreams())
@ -380,18 +384,22 @@ bool LimeSDRMIMO::startTx()
void LimeSDRMIMO::stopTx()
{
qDebug("LimeSDRMIMO::stopTx");
QMutexLocker mutexLocker(&m_mutex);
if (!m_runningTx) {
return;
}
if (!m_sinkThread) {
return;
}
QMutexLocker mutexLocker(&m_mutex);
qDebug("LimeSDRMIMO::stopTx");
m_runningTx = false;
m_sinkThread->stopWork();
delete m_sinkThread;
m_sinkThread = nullptr;
m_runningTx = false;
for (unsigned int channel = 0; channel < 2; channel++)
{

View File

@ -66,6 +66,7 @@ MetisMISO::MetisMISO(DeviceAPI *deviceAPI) :
MetisMISO::~MetisMISO()
{
qDebug("MetisMISO::~MetisMISO");
QObject::disconnect(
m_networkManager,
&QNetworkAccessManager::finished,
@ -77,6 +78,7 @@ MetisMISO::~MetisMISO()
if (m_running) {
stopRx();
}
qDebug("MetisMISO::~MetisMISO: end");
}
void MetisMISO::destroy()
@ -155,6 +157,7 @@ void MetisMISO::startMetis()
void MetisMISO::stopMetis()
{
qDebug("MetisMISO::stopMetis");
MetisMISOUDPHandler::MsgStartStop *message = MetisMISOUDPHandler::MsgStartStop::create(false);
m_udpHandler.getInputMessageQueue()->push(message);
}

View File

@ -168,7 +168,11 @@ void PlutoSDRMIMO::init()
bool PlutoSDRMIMO::startRx()
{
qDebug("PlutoSDRMIMO::startRx");
QMutexLocker mutexLocker(&m_mutex);
if (m_runningRx) {
return true;
}
if (!m_open)
{
@ -176,11 +180,7 @@ bool PlutoSDRMIMO::startRx()
return false;
}
QMutexLocker mutexLocker(&m_mutex);
if (m_runningRx) {
stopRx();
}
qDebug("PlutoSDRMIMO::startRx");
m_sourceThread = new PlutoSDRMIThread(m_plutoParams->getBox());
m_sampleMIFifo.reset();
@ -206,7 +206,11 @@ bool PlutoSDRMIMO::startRx()
bool PlutoSDRMIMO::startTx()
{
qDebug("PlutoSDRMIMO::startTx");
QMutexLocker mutexLocker(&m_mutex);
if (m_runningTx) {
return true;
}
if (!m_open)
{
@ -214,11 +218,7 @@ bool PlutoSDRMIMO::startTx()
return false;
}
QMutexLocker mutexLocker(&m_mutex);
if (m_runningTx) {
stopTx();
}
qDebug("PlutoSDRMIMO::startTx");
m_sinkThread = new PlutoSDRMOThread(m_plutoParams->getBox());
m_sampleMOFifo.reset();
@ -243,18 +243,22 @@ bool PlutoSDRMIMO::startTx()
void PlutoSDRMIMO::stopRx()
{
qDebug("PlutoSDRMIMO::stopRx");
QMutexLocker mutexLocker(&m_mutex);
if (!m_runningRx) {
return;
}
if (!m_sourceThread) {
return;
}
QMutexLocker mutexLocker(&m_mutex);
qDebug("PlutoSDRMIMO::stopRx");
m_runningRx = false;
m_sourceThread->stopWork();
delete m_sourceThread;
m_sourceThread = nullptr;
m_runningRx = false;
if (m_nbRx > 1) {
m_plutoParams->getBox()->closeSecondRx();
@ -270,18 +274,22 @@ void PlutoSDRMIMO::stopRx()
void PlutoSDRMIMO::stopTx()
{
qDebug("PlutoSDRMIMO::stopTx");
QMutexLocker mutexLocker(&m_mutex);
if (!m_runningTx) {
return;
}
if (!m_sinkThread) {
return;
}
QMutexLocker mutexLocker(&m_mutex);
qDebug("PlutoSDRMIMO::stopTx");
m_runningTx = false;
m_sinkThread->stopWork();
delete m_sinkThread;
m_sinkThread = nullptr;
m_runningTx = false;
if (m_nbTx > 1) {
m_plutoParams->getBox()->closeSecondTx();

View File

@ -124,7 +124,11 @@ void XTRXMIMO::init()
bool XTRXMIMO::startRx()
{
qDebug("XTRXMIMO::startRx");
QMutexLocker mutexLocker(&m_mutex);
if (m_runningRx) {
return true;
}
if (!m_open)
{
@ -132,11 +136,7 @@ bool XTRXMIMO::startRx()
return false;
}
QMutexLocker mutexLocker(&m_mutex);
if (m_runningRx) {
stopRx();
}
qDebug("XTRXMIMO::startRx");
m_sourceThread = new XTRXMIThread(m_deviceShared.m_dev->getDevice());
m_sampleMIFifo.reset();
@ -152,7 +152,11 @@ bool XTRXMIMO::startRx()
bool XTRXMIMO::startTx()
{
qDebug("XTRXMIMO::startTx");
QMutexLocker mutexLocker(&m_mutex);
if (m_runningTx) {
return true;
}
if (!m_open)
{
@ -160,11 +164,7 @@ bool XTRXMIMO::startTx()
return false;
}
QMutexLocker mutexLocker(&m_mutex);
if (m_runningRx) {
stopRx();
}
qDebug("XTRXMIMO::startTx");
m_sinkThread = new XTRXMOThread(m_deviceShared.m_dev->getDevice());
m_sampleMOFifo.reset();
@ -179,34 +179,42 @@ bool XTRXMIMO::startTx()
void XTRXMIMO::stopRx()
{
qDebug("XTRXMIMO::stopRx");
QMutexLocker mutexLocker(&m_mutex);
if (!m_runningRx){
return;
}
if (!m_sourceThread) {
return;
}
QMutexLocker mutexLocker(&m_mutex);
qDebug("XTRXMIMO::stopRx");
m_runningRx = false;
m_sourceThread->stopWork();
delete m_sourceThread;
m_sourceThread = nullptr;
m_runningRx = false;
}
void XTRXMIMO::stopTx()
{
qDebug("XTRXMIMO::stopTx");
QMutexLocker mutexLocker(&m_mutex);
if (!m_runningTx) {
return;
}
if (!m_sinkThread) {
return;
}
QMutexLocker mutexLocker(&m_mutex);
qDebug("XTRXMIMO::stopTx");
m_runningTx = false;
m_sinkThread->stopWork();
delete m_sinkThread;
m_sinkThread = nullptr;
m_runningTx = false;
}
QByteArray XTRXMIMO::serialize() const

View File

@ -68,11 +68,11 @@ Bladerf1Output::~Bladerf1Output()
delete m_networkManager;
if (m_running) {
stop();
Bladerf1Output::stop();
}
closeDevice();
m_deviceAPI->setBuddySharedPtr(0);
m_deviceAPI->setBuddySharedPtr(nullptr);
}
void Bladerf1Output::destroy()
@ -82,7 +82,7 @@ void Bladerf1Output::destroy()
bool Bladerf1Output::openDevice()
{
if (m_dev != 0) {
if (m_dev != nullptr) {
closeDevice();
}
@ -90,24 +90,24 @@ bool Bladerf1Output::openDevice()
m_sampleSourceFifo.resize(SampleSourceFifo::getSizePolicy(m_settings.m_devSampleRate));
if (m_deviceAPI->getSourceBuddies().size() > 0)
if (!m_deviceAPI->getSourceBuddies().empty())
{
DeviceAPI *sourceBuddy = m_deviceAPI->getSourceBuddies()[0];
DeviceBladeRF1Params *buddySharedParams = (DeviceBladeRF1Params *) sourceBuddy->getBuddySharedPtr();
const DeviceAPI *sourceBuddy = m_deviceAPI->getSourceBuddies()[0];
const DeviceBladeRF1Params *buddySharedParams = (DeviceBladeRF1Params *) sourceBuddy->getBuddySharedPtr();
if (buddySharedParams == 0)
if (buddySharedParams == nullptr)
{
qCritical("BladerfOutput::start: could not get shared parameters from buddy");
return false;
}
if (buddySharedParams->m_dev == 0) // device is not opened by buddy
if (buddySharedParams->m_dev == nullptr) // device is not opened by buddy
{
qCritical("BladerfOutput::start: could not get BladeRF handle from buddy");
return false;
}
m_sharedParams = *(buddySharedParams); // copy parameters from buddy
m_sharedParams = *buddySharedParams; // copy parameters from buddy
m_dev = m_sharedParams.m_dev; // get BladeRF handle
}
else
@ -121,7 +121,6 @@ bool Bladerf1Output::openDevice()
m_sharedParams.m_dev = m_dev;
}
// TODO: adjust USB transfer data according to sample rate
if ((res = bladerf_sync_config(m_dev, BLADERF_TX_X1, BLADERF_FORMAT_SC16_Q11, 64, 8192, 32, 10000)) < 0)
{
qCritical("BladerfOutput::start: bladerf_sync_config with return code %d", res);
@ -144,25 +143,24 @@ void Bladerf1Output::init()
bool Bladerf1Output::start()
{
// QMutexLocker mutexLocker(&m_mutex);
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_dev) {
return false;
}
if (m_running) stop();
m_bladerfThread = new Bladerf1OutputThread(m_dev, &m_sampleSourceFifo);
// mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
m_bladerfThread->setLog2Interpolation(m_settings.m_log2Interp);
m_bladerfThread->startWork();
qDebug("BladerfOutput::start: started");
m_running = true;
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
return true;
}
@ -171,7 +169,7 @@ void Bladerf1Output::closeDevice()
{
int res;
if (m_dev == 0) { // was never open
if (m_dev == nullptr) { // was never open
return;
}
@ -180,31 +178,36 @@ void Bladerf1Output::closeDevice()
qCritical("BladerfOutput::closeDevice: bladerf_enable_module with return code %d", res);
}
if (m_deviceAPI->getSourceBuddies().size() == 0)
if (m_deviceAPI->getSourceBuddies().empty())
{
qDebug("BladerfOutput::closeDevice: closing device since Rx side is not open");
if (m_dev != 0) // close BladeRF
if (m_dev != nullptr) // close BladeRF
{
bladerf_close(m_dev);
}
}
m_sharedParams.m_dev = 0;
m_dev = 0;
m_sharedParams.m_dev = nullptr;
m_dev = nullptr;
}
void Bladerf1Output::stop()
{
// QMutexLocker mutexLocker(&m_mutex);
if (m_bladerfThread != 0)
{
m_bladerfThread->stopWork();
delete m_bladerfThread;
m_bladerfThread = 0;
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
if (m_bladerfThread)
{
m_bladerfThread->stopWork();
delete m_bladerfThread;
m_bladerfThread = nullptr;
}
}
QByteArray Bladerf1Output::serialize() const
@ -269,7 +272,7 @@ bool Bladerf1Output::handleMessage(const Message& message)
{
if (MsgConfigureBladerf1::match(message))
{
MsgConfigureBladerf1& conf = (MsgConfigureBladerf1&) message;
auto& conf = (const MsgConfigureBladerf1&) message;
qDebug() << "BladerfOutput::handleMessage: MsgConfigureBladerf";
if (!applySettings(conf.getSettings(), conf.getSettingsKeys(), conf.getForce())) {
@ -280,7 +283,7 @@ bool Bladerf1Output::handleMessage(const Message& message)
}
else if (MsgStartStop::match(message))
{
MsgStartStop& cmd = (MsgStartStop&) message;
auto& cmd = (const MsgStartStop&) message;
qDebug() << "BladerfOutput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
if (cmd.getStartStop())
@ -312,7 +315,7 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, const
bool forwardChange = false;
bool suspendOwnThread = false;
bool threadWasRunning = false;
// QMutexLocker mutexLocker(&m_mutex);
QMutexLocker mutexLocker(&m_mutex);
if (settingsKeys.contains("devSampleRate") ||
settingsKeys.contains("log2Interp") || force)
@ -320,17 +323,11 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, const
suspendOwnThread = true;
}
if (suspendOwnThread)
{
if (m_bladerfThread)
{
if (m_bladerfThread->isRunning())
if (suspendOwnThread && m_bladerfThread && m_bladerfThread->isRunning())
{
m_bladerfThread->stopWork();
threadWasRunning = true;
}
}
}
if (settingsKeys.contains("devSampleRate") ||
settingsKeys.contains("log2Interp") || force)
@ -350,7 +347,7 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, const
{
forwardChange = true;
if (m_dev != 0)
if (m_dev != nullptr)
{
unsigned int actualSamplerate;
@ -366,16 +363,14 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, const
{
forwardChange = true;
if (m_bladerfThread != 0)
if (m_bladerfThread != nullptr)
{
m_bladerfThread->setLog2Interpolation(settings.m_log2Interp);
qDebug() << "BladerfOutput::applySettings: set interpolation to " << (1<<settings.m_log2Interp);
}
}
if (settingsKeys.contains("vga1") || force)
{
if (m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("vga1") || force))
{
if (bladerf_set_txvga1(m_dev, settings.m_vga1) != 0) {
qDebug("BladerfOutput::applySettings: bladerf_set_txvga1() failed");
@ -383,11 +378,8 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, const
qDebug() << "BladerfOutput::applySettings: VGA1 gain set to " << settings.m_vga1;
}
}
}
if (settingsKeys.contains("vga2") || force)
{
if(m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("vga2") || force))
{
if (bladerf_set_txvga2(m_dev, settings.m_vga2) != 0) {
qDebug("BladerfOutput::applySettings:bladerf_set_rxvga2() failed");
@ -395,19 +387,16 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, const
qDebug() << "BladerfOutput::applySettings: VGA2 gain set to " << settings.m_vga2;
}
}
}
if (settingsKeys.contains("xb200") || force)
{
if (m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("xb200") || force))
{
bool changeSettings;
if (m_deviceAPI->getSourceBuddies().size() > 0)
if (!m_deviceAPI->getSourceBuddies().empty())
{
DeviceAPI *buddy = m_deviceAPI->getSourceBuddies()[0];
if (buddy->getDeviceSourceEngine()->state() == DSPDeviceSourceEngine::StRunning) { // Tx side running
if (buddy->getDeviceSourceEngine()->state() == DSPDeviceSourceEngine::State::StRunning) { // Tx side running
changeSettings = false;
} else {
changeSettings = true;
@ -440,11 +429,8 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, const
m_sharedParams.m_xb200Attached = settings.m_xb200;
}
}
}
if (settingsKeys.contains("xb200Path") || force)
{
if (m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("xb200Path") || force))
{
if (bladerf_xb200_set_path(m_dev, BLADERF_MODULE_TX, settings.m_xb200Path) != 0) {
qDebug("BladerfOutput::applySettings: bladerf_xb200_set_path(BLADERF_MODULE_TX) failed");
@ -452,11 +438,8 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, const
qDebug() << "BladerfOutput::applySettings: set xb200 path to " << settings.m_xb200Path;
}
}
}
if (settingsKeys.contains("xb200Filter") || force)
{
if (m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("xb200Filter") || force))
{
if (bladerf_xb200_set_filterbank(m_dev, BLADERF_MODULE_TX, settings.m_xb200Filter) != 0) {
qDebug("BladerfOutput::applySettings: bladerf_xb200_set_filterbank(BLADERF_MODULE_TX) failed");
@ -464,11 +447,8 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, const
qDebug() << "BladerfOutput::applySettings: set xb200 filter to " << settings.m_xb200Filter;
}
}
}
if (settingsKeys.contains("bandwidth") || force)
{
if (m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("bandwidth") || force))
{
unsigned int actualBandwidth;
@ -478,19 +458,15 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, const
qDebug() << "BladerfOutput::applySettings: bladerf_set_bandwidth(BLADERF_MODULE_TX) actual bandwidth is " << actualBandwidth;
}
}
}
if (settingsKeys.contains("centerFrequency"))
{
forwardChange = true;
if (m_dev != 0)
{
if (bladerf_set_frequency( m_dev, BLADERF_MODULE_TX, settings.m_centerFrequency ) != 0) {
if ((m_dev != nullptr) && (bladerf_set_frequency( m_dev, BLADERF_MODULE_TX, settings.m_centerFrequency ) != 0)) {
qDebug("BladerfOutput::applySettings: bladerf_set_frequency(%lld) failed", settings.m_centerFrequency);
}
}
}
if (threadWasRunning)
{
@ -515,7 +491,7 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, const
if (forwardChange)
{
int sampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2Interp);
DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, m_settings.m_centerFrequency);
auto *notif = new DSPSignalNotification(sampleRate, m_settings.m_centerFrequency);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
}
@ -604,7 +580,7 @@ void Bladerf1Output::webapiUpdateDeviceSettings(
settings.m_log2Interp = response.getBladeRf1OutputSettings()->getLog2Interp();
}
if (deviceSettingsKeys.contains("xb200")) {
settings.m_xb200 = response.getBladeRf1OutputSettings()->getXb200() == 0 ? 0 : 1;
settings.m_xb200 = response.getBladeRf1OutputSettings()->getXb200() == 0 ? false : true;
}
if (deviceSettingsKeys.contains("xb200Path")) {
settings.m_xb200Path = static_cast<bladerf_xb200_path>(response.getBladeRf1OutputSettings()->getXb200Path());
@ -619,10 +595,10 @@ void Bladerf1Output::webapiUpdateDeviceSettings(
settings.m_reverseAPIAddress = *response.getBladeRf1OutputSettings()->getReverseApiAddress();
}
if (deviceSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getBladeRf1OutputSettings()->getReverseApiPort();
settings.m_reverseAPIPort = (uint16_t) response.getBladeRf1OutputSettings()->getReverseApiPort();
}
if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getBladeRf1OutputSettings()->getReverseApiDeviceIndex();
settings.m_reverseAPIDeviceIndex = (uint16_t) response.getBladeRf1OutputSettings()->getReverseApiDeviceIndex();
}
}
@ -656,7 +632,7 @@ int Bladerf1Output::webapiRun(
void Bladerf1Output::webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const BladeRF1OutputSettings& settings, bool force)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
auto *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(1); // single Tx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("BladeRF1"));
@ -700,8 +676,8 @@ void Bladerf1Output::webapiReverseSendSettings(const QList<QString>& deviceSetti
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
@ -714,7 +690,7 @@ void Bladerf1Output::webapiReverseSendSettings(const QList<QString>& deviceSetti
void Bladerf1Output::webapiReverseSendStartStop(bool start)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
auto *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(1); // single Tx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("BladeRF1"));
@ -726,8 +702,8 @@ void Bladerf1Output::webapiReverseSendStartStop(bool start)
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
QNetworkReply *reply;
@ -742,7 +718,7 @@ void Bladerf1Output::webapiReverseSendStartStop(bool start)
delete swgDeviceSettings;
}
void Bladerf1Output::networkManagerFinished(QNetworkReply *reply)
void Bladerf1Output::networkManagerFinished(QNetworkReply *reply) const
{
QNetworkReply::NetworkError replyError = reply->error();

View File

@ -74,10 +74,10 @@ public:
return new MsgStartStop(startStop);
}
protected:
private:
bool m_startStop;
MsgStartStop(bool startStop) :
explicit MsgStartStop(bool startStop) :
Message(),
m_startStop(startStop)
{ }
@ -100,44 +100,44 @@ public:
{ }
};
Bladerf1Output(DeviceAPI *deviceAPI);
virtual ~Bladerf1Output();
virtual void destroy();
explicit Bladerf1Output(DeviceAPI *deviceAPI);
~Bladerf1Output() final;
void destroy() final;
virtual void init();
virtual bool start();
virtual void stop();
void init() final;
bool start() final;
void stop() final;
virtual QByteArray serialize() const;
virtual bool deserialize(const QByteArray& data);
QByteArray serialize() const final;
bool deserialize(const QByteArray& data) final;
virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; }
virtual const QString& getDeviceDescription() const;
virtual int getSampleRate() const;
virtual void setSampleRate(int sampleRate) { (void) sampleRate; }
virtual quint64 getCenterFrequency() const;
virtual void setCenterFrequency(qint64 centerFrequency);
void setMessageQueueToGUI(MessageQueue *queue) final { m_guiMessageQueue = queue; }
const QString& getDeviceDescription() const final;
int getSampleRate() const final;
void setSampleRate(int sampleRate) final { (void) sampleRate; }
quint64 getCenterFrequency() const final;
void setCenterFrequency(qint64 centerFrequency) final;
virtual bool handleMessage(const Message& message);
bool handleMessage(const Message& message) final;
virtual int webapiSettingsGet(
int webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiSettingsPutPatch(
int webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiRunGet(
int webapiRunGet(
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiRun(
int webapiRun(
bool run,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
QString& errorMessage) final;
static void webapiFormatDeviceSettings(
SWGSDRangel::SWGDeviceSettings& response,
@ -150,7 +150,7 @@ public:
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
QRecursiveMutex m_mutex;
BladeRF1OutputSettings m_settings;
struct bladerf* m_dev;
Bladerf1OutputThread* m_bladerfThread;
@ -167,7 +167,7 @@ private:
void webapiReverseSendStartStop(bool start);
private slots:
void networkManagerFinished(QNetworkReply *reply);
void networkManagerFinished(QNetworkReply *reply) const;
};
#endif // INCLUDE_BLADERFOUTPUT_H

View File

@ -399,14 +399,14 @@ void BladeRF2Output::stop()
qDebug("BladeRF2Output::stop: SO mode. Just stop and delete the thread");
bladeRF2OutputThread->stopWork();
delete bladeRF2OutputThread;
m_thread = 0;
m_thread = nullptr;
// remove old thread address from buddies (reset in all buddies)
const std::vector<DeviceAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
std::vector<DeviceAPI*>::const_iterator it = sinkBuddies.begin();
for (; it != sinkBuddies.end(); ++it) {
((DeviceBladeRF2Shared*) (*it)->getBuddySharedPtr())->m_sink->setThread(0);
((DeviceBladeRF2Shared*) (*it)->getBuddySharedPtr())->m_sink->setThread(nullptr);
}
m_deviceShared.m_dev->closeTx(0); // close the unique channel
@ -422,7 +422,7 @@ void BladeRF2Output::stop()
for (int i = 0; i < nbOriginalChannels-1; i++) // save original FIFO references
{
fifos[i] = bladeRF2OutputThread->getFifo(i);
stillActiveFIFO = stillActiveFIFO || (bladeRF2OutputThread->getFifo(i) != 0);
stillActiveFIFO = stillActiveFIFO || (bladeRF2OutputThread->getFifo(i) != nullptr);
log2Interps[i] = bladeRF2OutputThread->getLog2Interpolation(i);
}
@ -450,7 +450,7 @@ void BladeRF2Output::stop()
std::vector<DeviceAPI*>::const_iterator it = sinkBuddies.begin();
for (; it != sinkBuddies.end(); ++it) {
((DeviceBladeRF2Shared*) (*it)->getBuddySharedPtr())->m_sink->setThread(0);
((DeviceBladeRF2Shared*) (*it)->getBuddySharedPtr())->m_sink->setThread(nullptr);
}
// close all channels
@ -479,11 +479,9 @@ void BladeRF2Output::stop()
else // remove channel from existing thread
{
qDebug("BladeRF2Output::stop: MO mode. Not changing MO configuration. Just remove FIFO reference");
bladeRF2OutputThread->setFifo(requestedChannel, 0); // remove FIFO
bladeRF2OutputThread->setFifo(requestedChannel, nullptr); // remove FIFO
}
applySettings(m_settings, QList<QString>(), true); // re-apply forcibly to set sample rate with the new number of channels
m_running = false;
}

View File

@ -45,9 +45,7 @@ MESSAGE_CLASS_DEFINITION(FileOutput::MsgReportFileOutputStreamTiming, Message)
FileOutput::FileOutput(DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
m_settings(),
m_fileOutputWorker(nullptr),
m_deviceDescription("FileOutput"),
m_startingTimeStamp(0),
m_masterTimer(deviceAPI->getMasterTimer())
{
m_deviceAPI->setNbSinkStreams(1);
@ -57,7 +55,7 @@ FileOutput::FileOutput(DeviceAPI *deviceAPI) :
FileOutput::~FileOutput()
{
delete m_networkManager;
stop();
FileOutput::stop();
}
void FileOutput::destroy()
@ -74,7 +72,7 @@ void FileOutput::openFileStream()
m_ofstream.open(m_settings.m_fileName.toStdString().c_str(), std::ios::binary);
FileRecord::Header header;
int actualSampleRate = m_settings.m_sampleRate * (1<<m_settings.m_log2Interp);
auto actualSampleRate = (int) (m_settings.m_sampleRate * (1<<m_settings.m_log2Interp));
header.sampleRate = actualSampleRate;
header.centerFrequency = m_settings.m_centerFrequency;
m_startingTimeStamp = QDateTime::currentMSecsSinceEpoch();
@ -94,19 +92,24 @@ void FileOutput::init()
bool FileOutput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
qDebug() << "FileOutput::start";
openFileStream();
m_fileOutputWorker = new FileOutputWorker(&m_ofstream, &m_sampleSourceFifo);
m_fileOutputWorker->moveToThread(&m_fileOutputWorkerThread);
m_fileOutputWorker->setSamplerate(m_settings.m_sampleRate);
m_fileOutputWorker->setSamplerate((int) m_settings.m_sampleRate);
m_fileOutputWorker->setLog2Interpolation(m_settings.m_log2Interp);
m_fileOutputWorker->connectTimer(m_masterTimer);
startWorker();
m_running = true;
mutexLocker.unlock();
//applySettings(m_generalSettings, m_settings, true);
qDebug("FileOutput::start: started");
if (getMessageQueueToGUI())
@ -120,9 +123,15 @@ bool FileOutput::start()
void FileOutput::stop()
{
qDebug() << "FileSourceInput::stop";
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
qDebug() << "FileSourceInput::stop";
m_running = false;
if (m_fileOutputWorker)
{
stopWorker();
@ -188,7 +197,7 @@ const QString& FileOutput::getDeviceDescription() const
int FileOutput::getSampleRate() const
{
return m_settings.m_sampleRate;
return (int) m_settings.m_sampleRate;
}
quint64 FileOutput::getCenterFrequency() const
@ -220,14 +229,14 @@ bool FileOutput::handleMessage(const Message& message)
{
if (MsgConfigureFileOutputName::match(message))
{
MsgConfigureFileOutputName& conf = (MsgConfigureFileOutputName&) message;
auto& conf = (const MsgConfigureFileOutputName&) message;
m_settings.m_fileName = conf.getFileName();
openFileStream();
return true;
}
else if (MsgStartStop::match(message))
{
MsgStartStop& cmd = (MsgStartStop&) message;
auto& cmd = (const MsgStartStop&) message;
qDebug() << "FileOutput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
if (cmd.getStartStop())
@ -250,16 +259,16 @@ bool FileOutput::handleMessage(const Message& message)
else if (MsgConfigureFileOutput::match(message))
{
qDebug() << "FileOutput::handleMessage: MsgConfigureFileOutput";
MsgConfigureFileOutput& conf = (MsgConfigureFileOutput&) message;
auto& conf = (const MsgConfigureFileOutput&) message;
applySettings(conf.getSettings(), conf.getSettingsKeys(), conf.getForce());
return true;
}
else if (MsgConfigureFileOutputWork::match(message))
{
MsgConfigureFileOutputWork& conf = (MsgConfigureFileOutputWork&) message;
auto& conf = (const MsgConfigureFileOutputWork&) message;
bool working = conf.isWorking();
if (m_fileOutputWorker != 0)
if (m_fileOutputWorker != nullptr)
{
if (working) {
startWorker();
@ -272,11 +281,9 @@ bool FileOutput::handleMessage(const Message& message)
}
else if (MsgConfigureFileOutputStreamTiming::match(message))
{
MsgReportFileOutputStreamTiming *report;
if (m_fileOutputWorker != 0 && getMessageQueueToGUI())
if (m_fileOutputWorker != nullptr && getMessageQueueToGUI())
{
report = MsgReportFileOutputStreamTiming::create(m_fileOutputWorker->getSamplesCount());
auto *report = MsgReportFileOutputStreamTiming::create(m_fileOutputWorker->getSamplesCount());
getMessageQueueToGUI()->push(report);
}
@ -301,8 +308,8 @@ void FileOutput::applySettings(const FileOutputSettings& settings, const QList<Q
if (force || settingsKeys.contains("sampleRate"))
{
if (m_fileOutputWorker != 0) {
m_fileOutputWorker->setSamplerate(settings.m_sampleRate);
if (m_fileOutputWorker != nullptr) {
m_fileOutputWorker->setSamplerate((int) settings.m_sampleRate);
}
forwardChange = true;
@ -310,7 +317,7 @@ void FileOutput::applySettings(const FileOutputSettings& settings, const QList<Q
if (force || settingsKeys.contains("log2Interp"))
{
if (m_fileOutputWorker != 0) {
if (m_fileOutputWorker != nullptr) {
m_fileOutputWorker->setLog2Interpolation(settings.m_log2Interp);
}
@ -338,7 +345,7 @@ void FileOutput::applySettings(const FileOutputSettings& settings, const QList<Q
m_settings.m_centerFrequency,
m_settings.m_sampleRate,
m_settings.m_log2Interp);
DSPSignalNotification *notif = new DSPSignalNotification(m_settings.m_sampleRate, m_settings.m_centerFrequency);
auto *notif = new DSPSignalNotification((int) m_settings.m_sampleRate, m_settings.m_centerFrequency);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
}
}
@ -448,16 +455,16 @@ void FileOutput::webapiUpdateDeviceSettings(
settings.m_reverseAPIAddress = *response.getFileOutputSettings()->getReverseApiAddress();
}
if (deviceSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getFileOutputSettings()->getReverseApiPort();
settings.m_reverseAPIPort = (uint16_t) response.getFileOutputSettings()->getReverseApiPort();
}
if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getFileOutputSettings()->getReverseApiDeviceIndex();
settings.m_reverseAPIDeviceIndex = (uint16_t) response.getFileOutputSettings()->getReverseApiDeviceIndex();
}
}
void FileOutput::webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const FileOutputSettings& settings, bool force)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
auto *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(1); // single Tx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("FileOutput"));
@ -486,8 +493,8 @@ void FileOutput::webapiReverseSendSettings(const QList<QString>& deviceSettingsK
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
@ -500,7 +507,7 @@ void FileOutput::webapiReverseSendSettings(const QList<QString>& deviceSettingsK
void FileOutput::webapiReverseSendStartStop(bool start)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
auto *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(1); // single Tx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("FileOutput"));
@ -512,8 +519,8 @@ void FileOutput::webapiReverseSendStartStop(bool start)
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
QNetworkReply *reply;
@ -528,7 +535,7 @@ void FileOutput::webapiReverseSendStartStop(bool start)
delete swgDeviceSettings;
}
void FileOutput::networkManagerFinished(QNetworkReply *reply)
void FileOutput::networkManagerFinished(QNetworkReply *reply) const
{
QNetworkReply::NetworkError replyError = reply->error();

View File

@ -76,10 +76,10 @@ public:
return new MsgStartStop(startStop);
}
protected:
private:
bool m_startStop;
MsgStartStop(bool startStop) :
explicit MsgStartStop(bool startStop) :
Message(),
m_startStop(startStop)
{ }
@ -99,7 +99,7 @@ public:
private:
QString m_fileName;
MsgConfigureFileOutputName(const QString& fileName) :
explicit MsgConfigureFileOutputName(const QString& fileName) :
Message(),
m_fileName(fileName)
{ }
@ -119,7 +119,7 @@ public:
private:
bool m_working;
MsgConfigureFileOutputWork(bool working) :
explicit MsgConfigureFileOutputWork(bool working) :
Message(),
m_working(working)
{ }
@ -153,10 +153,10 @@ public:
return new MsgReportFileOutputGeneration(acquisition);
}
protected:
private:
bool m_acquisition;
MsgReportFileOutputGeneration(bool acquisition) :
explicit MsgReportFileOutputGeneration(bool acquisition) :
Message(),
m_acquisition(acquisition)
{ }
@ -173,54 +173,54 @@ public:
return new MsgReportFileOutputStreamTiming(samplesCount);
}
protected:
private:
std::size_t m_samplesCount;
MsgReportFileOutputStreamTiming(std::size_t samplesCount) :
explicit MsgReportFileOutputStreamTiming(std::size_t samplesCount) :
Message(),
m_samplesCount(samplesCount)
{ }
};
FileOutput(DeviceAPI *deviceAPI);
virtual ~FileOutput();
virtual void destroy();
explicit FileOutput(DeviceAPI *deviceAPI);
~FileOutput() final;
void destroy() final;
virtual void init();
virtual bool start();
virtual void stop();
void init() final;
bool start() final;
void stop() final;
virtual QByteArray serialize() const;
virtual bool deserialize(const QByteArray& data);
QByteArray serialize() const final;
bool deserialize(const QByteArray& data) final;
virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; }
virtual const QString& getDeviceDescription() const;
virtual int getSampleRate() const;
virtual void setSampleRate(int sampleRate) { (void) sampleRate; }
virtual quint64 getCenterFrequency() const;
virtual void setCenterFrequency(qint64 centerFrequency);
void setMessageQueueToGUI(MessageQueue *queue) final { m_guiMessageQueue = queue; }
const QString& getDeviceDescription() const final;
int getSampleRate() const final;
void setSampleRate(int sampleRate) final { (void) sampleRate; }
quint64 getCenterFrequency() const final;
void setCenterFrequency(qint64 centerFrequency) final;
std::time_t getStartingTimeStamp() const;
virtual bool handleMessage(const Message& message);
bool handleMessage(const Message& message) final;
virtual int webapiSettingsGet(
int webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiSettingsPutPatch(
int webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiRunGet(
int webapiRunGet(
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiRun(
int webapiRun(
bool run,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
QString& errorMessage) final;
static void webapiFormatDeviceSettings(
SWGSDRangel::SWGDeviceSettings& response,
@ -234,12 +234,13 @@ public:
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
bool m_running = false;
FileOutputSettings m_settings;
std::ofstream m_ofstream;
FileOutputWorker* m_fileOutputWorker;
FileOutputWorker* m_fileOutputWorker = nullptr;
QThread m_fileOutputWorkerThread;
QString m_deviceDescription;
qint64 m_startingTimeStamp;
qint64 m_startingTimeStamp = 0;
const QTimer& m_masterTimer;
QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
@ -252,7 +253,7 @@ private:
void webapiReverseSendStartStop(bool start);
private slots:
void networkManagerFinished(QNetworkReply *reply);
void networkManagerFinished(QNetworkReply *reply) const;
};
#endif // INCLUDE_FILEOUTPUT_H

View File

@ -129,27 +129,28 @@ void HackRFOutput::init()
bool HackRFOutput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_dev) {
return false;
}
if (m_running) {
stop();
return true;
}
m_hackRFThread = new HackRFOutputThread(m_dev, &m_sampleSourceFifo);
// mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
m_hackRFThread->setLog2Interpolation(m_settings.m_log2Interp);
m_hackRFThread->setFcPos((int) m_settings.m_fcPos);
m_hackRFThread->startWork();
m_running = true;
mutexLocker.unlock();
qDebug("HackRFOutput::start: started");
m_running = true;
applySettings(m_settings, QList<QString>(), true);
return true;
}
@ -173,8 +174,14 @@ void HackRFOutput::closeDevice()
void HackRFOutput::stop()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
qDebug("HackRFOutput::stop");
// QMutexLocker mutexLocker(&m_mutex);
m_running = false;
if(m_hackRFThread != 0)
{
@ -182,8 +189,6 @@ void HackRFOutput::stop()
delete m_hackRFThread;
m_hackRFThread = 0;
}
m_running = false;
}
QByteArray HackRFOutput::serialize() const

View File

@ -380,14 +380,17 @@ void LimeSDROutput::init()
bool LimeSDROutput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_deviceShared.m_deviceParams->getDevice()) {
return false;
}
if (m_running) { stop(); }
if (!acquireChannel())
{
if (!acquireChannel()) {
return false;
}
@ -396,20 +399,25 @@ bool LimeSDROutput::start()
m_limeSDROutputThread = new LimeSDROutputThread(&m_streamId, &m_sampleSourceFifo);
qDebug("LimeSDROutput::start: thread created");
applySettings(m_settings, QList<QString>(), true);
m_limeSDROutputThread->setLog2Interpolation(m_settings.m_log2SoftInterp);
m_limeSDROutputThread->startWork();
m_deviceShared.m_thread = m_limeSDROutputThread;
m_running = true;
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
return true;
}
void LimeSDROutput::stop()
{
if (!m_running) {
return;
}
qDebug("LimeSDROutput::stop");
m_running = false;
if (m_limeSDROutputThread)
{
@ -419,7 +427,6 @@ void LimeSDROutput::stop()
}
m_deviceShared.m_thread = 0;
m_running = false;
releaseChannel();
}

View File

@ -102,34 +102,44 @@ void PlutoSDROutput::init()
bool PlutoSDROutput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_deviceShared.m_deviceParams->getBox())
{
qCritical("PlutoSDROutput::start: device not open");
return false;
}
if (m_running) {
stop();
}
// start / stop streaming is done in the thread.
m_plutoSDROutputThread = new PlutoSDROutputThread(PLUTOSDR_BLOCKSIZE_SAMPLES, m_deviceShared.m_deviceParams->getBox(), &m_sampleSourceFifo);
qDebug("PlutoSDROutput::start: thread created");
applySettings(m_settings, QList<QString>(), true);
m_plutoSDROutputThread->setLog2Interpolation(m_settings.m_log2Interp);
m_plutoSDROutputThread->startWork();
m_deviceShared.m_thread = m_plutoSDROutputThread;
m_running = true;
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
return true;
}
void PlutoSDROutput::stop()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
if (m_plutoSDROutputThread != 0)
{
m_plutoSDROutputThread->stopWork();
@ -138,7 +148,6 @@ void PlutoSDROutput::stop()
}
m_deviceShared.m_thread = 0;
m_running = false;
}
QByteArray PlutoSDROutput::serialize() const

View File

@ -47,6 +47,7 @@ MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgRequestFixedData, Message)
RemoteOutput::RemoteOutput(DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
m_running(false),
m_settings(),
m_centerFrequency(435000000),
m_sampleRate(48000),
@ -83,7 +84,7 @@ RemoteOutput::~RemoteOutput()
this,
&RemoteOutput::networkManagerFinished
);
stop();
RemoteOutput::stop();
delete m_networkManager;
}
@ -95,6 +96,11 @@ void RemoteOutput::destroy()
bool RemoteOutput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
qDebug() << "RemoteOutput::start";
m_remoteOutputWorker = new RemoteOutputWorker(&m_sampleSourceFifo);
@ -105,6 +111,7 @@ bool RemoteOutput::start()
m_remoteOutputWorker->setNbBlocksFEC(m_settings.m_nbFECBlocks);
m_remoteOutputWorker->connectTimer(m_masterTimer);
startWorker();
m_running = true;
mutexLocker.unlock();
applySampleRate();
@ -121,9 +128,15 @@ void RemoteOutput::init()
void RemoteOutput::stop()
{
qDebug() << "RemoteOutput::stop";
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
qDebug() << "RemoteOutput::stop";
m_running = false;
if (m_remoteOutputWorker)
{
stopWorker();
@ -198,13 +211,13 @@ bool RemoteOutput::handleMessage(const Message& message)
if (MsgConfigureRemoteOutput::match(message))
{
qDebug() << "RemoteOutput::handleMessage:" << message.getIdentifier();
MsgConfigureRemoteOutput& conf = (MsgConfigureRemoteOutput&) message;
auto& conf = (const MsgConfigureRemoteOutput&) message;
applySettings(conf.getSettings(), conf.getSettingsKeys(), conf.getForce());
return true;
}
else if (MsgConfigureRemoteOutputWork::match(message))
{
MsgConfigureRemoteOutputWork& conf = (MsgConfigureRemoteOutputWork&) message;
auto& conf = (const MsgConfigureRemoteOutputWork&) message;
bool working = conf.isWorking();
if (m_remoteOutputWorker != nullptr)
@ -220,7 +233,7 @@ bool RemoteOutput::handleMessage(const Message& message)
}
else if (MsgStartStop::match(message))
{
MsgStartStop& cmd = (MsgStartStop&) message;
auto& cmd = (const MsgStartStop&) message;
qDebug() << "RemoteOutput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
if (cmd.getStartStop())
@ -242,7 +255,7 @@ bool RemoteOutput::handleMessage(const Message& message)
}
else if (MsgConfigureRemoteOutputChunkCorrection::match(message))
{
MsgConfigureRemoteOutputChunkCorrection& conf = (MsgConfigureRemoteOutputChunkCorrection&) message;
auto& conf = (const MsgConfigureRemoteOutputChunkCorrection&) message;
if (m_remoteOutputWorker != nullptr) {
m_remoteOutputWorker->setChunkCorrection(conf.getChunkCorrection());
@ -274,31 +287,24 @@ void RemoteOutput::applySettings(const RemoteOutputSettings& settings, const QLi
qDebug() << "RemoteOutput::applySettings: force:" << force << settings.getDebugString(settingsKeys, force);
QMutexLocker mutexLocker(&m_mutex);
if (force ||
if ((force ||
settingsKeys.contains("dataAddress") ||
settingsKeys.contains("dataPort"))
settingsKeys.contains("dataPort")) && m_remoteOutputWorker)
{
if (m_remoteOutputWorker) {
m_remoteOutputWorker->setDataAddress(settings.m_dataAddress, settings.m_dataPort);
}
}
if (force || settingsKeys.contains("nbFECBlocks"))
if ((force || settingsKeys.contains("nbFECBlocks")) && m_remoteOutputWorker)
{
if (m_remoteOutputWorker) {
m_remoteOutputWorker->setNbBlocksFEC(settings.m_nbFECBlocks);
}
}
if (force || settingsKeys.contains("nbTxBytes"))
{
if (m_remoteOutputWorker)
if ((force || settingsKeys.contains("nbTxBytes")) && m_remoteOutputWorker)
{
stopWorker();
m_remoteOutputWorker->setNbTxBytes(settings.m_nbTxBytes);
startWorker();
}
}
mutexLocker.unlock();
@ -320,7 +326,7 @@ void RemoteOutput::applySettings(const RemoteOutputSettings& settings, const QLi
void RemoteOutput::applyCenterFrequency()
{
DSPSignalNotification *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
auto *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
}
@ -331,10 +337,11 @@ void RemoteOutput::applySampleRate()
}
m_tickMultiplier = 480000 / m_sampleRate;
m_tickMultiplier = m_tickMultiplier < 1 ? 1 : m_tickMultiplier > 10 ? 10 : m_tickMultiplier;
m_tickMultiplier = m_tickMultiplier < 1 ? 1 : m_tickMultiplier;
m_tickMultiplier = m_tickMultiplier > 10 ? 10 : m_tickMultiplier;
m_greaterTickCount = 0;
DSPSignalNotification *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
auto *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
}
@ -415,13 +422,13 @@ void RemoteOutput::webapiUpdateDeviceSettings(
settings.m_apiAddress = *response.getRemoteOutputSettings()->getApiAddress();
}
if (deviceSettingsKeys.contains("apiPort")) {
settings.m_apiPort = response.getRemoteOutputSettings()->getApiPort();
settings.m_apiPort = (quint16) response.getRemoteOutputSettings()->getApiPort();
}
if (deviceSettingsKeys.contains("dataAddress")) {
settings.m_dataAddress = *response.getRemoteOutputSettings()->getDataAddress();
}
if (deviceSettingsKeys.contains("dataPort")) {
settings.m_dataPort = response.getRemoteOutputSettings()->getDataPort();
settings.m_dataPort = (quint16) response.getRemoteOutputSettings()->getDataPort();
}
if (deviceSettingsKeys.contains("deviceIndex")) {
settings.m_deviceIndex = response.getRemoteOutputSettings()->getDeviceIndex();
@ -436,10 +443,10 @@ void RemoteOutput::webapiUpdateDeviceSettings(
settings.m_reverseAPIAddress = *response.getRemoteOutputSettings()->getReverseApiAddress();
}
if (deviceSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getRemoteOutputSettings()->getReverseApiPort();
settings.m_reverseAPIPort = (quint16) response.getRemoteOutputSettings()->getReverseApiPort();
}
if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getRemoteOutputSettings()->getReverseApiDeviceIndex();
settings.m_reverseAPIDeviceIndex = (uint16_t) response.getRemoteOutputSettings()->getReverseApiDeviceIndex();
}
}
@ -476,10 +483,10 @@ void RemoteOutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& re
response.getRemoteOutputSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex);
}
void RemoteOutput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response)
void RemoteOutput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response) const
{
uint64_t nowus = TimeUtil::nowus();
response.getRemoteOutputReport()->setTvSec(nowus / 1000000U);
response.getRemoteOutputReport()->setTvSec((qint32) (nowus / 1000000U));
response.getRemoteOutputReport()->setTvUSec(nowus % 1000000U);
response.getRemoteOutputReport()->setCenterFrequency(m_centerFrequency);
response.getRemoteOutputReport()->setSampleRate(m_sampleRate);
@ -653,7 +660,7 @@ void RemoteOutput::queueLengthCompensation(
void RemoteOutput::webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const RemoteOutputSettings& settings, bool force)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
auto *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(1); // single Tx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("RemoteOutput"));
@ -694,8 +701,8 @@ void RemoteOutput::webapiReverseSendSettings(const QList<QString>& deviceSetting
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
@ -708,7 +715,7 @@ void RemoteOutput::webapiReverseSendSettings(const QList<QString>& deviceSetting
void RemoteOutput::webapiReverseSendStartStop(bool start)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
auto *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(1); // single Tx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("RemoteOutput"));
@ -720,8 +727,8 @@ void RemoteOutput::webapiReverseSendStartStop(bool start)
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
QNetworkReply *reply;

View File

@ -83,7 +83,7 @@ public:
private:
bool m_working;
MsgConfigureRemoteOutputWork(bool working) :
explicit MsgConfigureRemoteOutputWork(bool working) :
Message(),
m_working(working)
{ }
@ -99,10 +99,10 @@ public:
return new MsgStartStop(startStop);
}
protected:
private:
bool m_startStop;
MsgStartStop(bool startStop) :
explicit MsgStartStop(bool startStop) :
Message(),
m_startStop(startStop)
{ }
@ -122,7 +122,7 @@ public:
private:
int m_chunkCorrection;
MsgConfigureRemoteOutputChunkCorrection(int chunkCorrection) :
explicit MsgConfigureRemoteOutputChunkCorrection(int chunkCorrection) :
Message(),
m_chunkCorrection(chunkCorrection)
{ }
@ -153,7 +153,7 @@ public:
private:
RemoteData m_remoteData;
MsgReportRemoteData(const RemoteData& remoteData) :
explicit MsgReportRemoteData(const RemoteData& remoteData) :
Message(),
m_remoteData(remoteData)
{}
@ -182,7 +182,7 @@ public:
private:
RemoteData m_remoteData;
MsgReportRemoteFixedData(const RemoteData& remoteData) :
explicit MsgReportRemoteFixedData(const RemoteData& remoteData) :
Message(),
m_remoteData(remoteData)
{}
@ -203,49 +203,49 @@ public:
};
RemoteOutput(DeviceAPI *deviceAPI);
virtual ~RemoteOutput();
virtual void destroy();
explicit RemoteOutput(DeviceAPI *deviceAPI);
~RemoteOutput() final;
void destroy() final;
virtual void init();
virtual bool start();
virtual void stop();
void init() final;
bool start() final;
void stop() final;
virtual QByteArray serialize() const;
virtual bool deserialize(const QByteArray& data);
QByteArray serialize() const final;
bool deserialize(const QByteArray& data) final;
virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; }
virtual const QString& getDeviceDescription() const;
virtual int getSampleRate() const;
virtual void setSampleRate(int sampleRate) { (void) sampleRate; }
virtual quint64 getCenterFrequency() const;
virtual void setCenterFrequency(qint64 centerFrequency) { (void) centerFrequency; }
void setMessageQueueToGUI(MessageQueue *queue) final { m_guiMessageQueue = queue; }
const QString& getDeviceDescription() const final;
int getSampleRate() const final;
void setSampleRate(int sampleRate) final { (void) sampleRate; }
quint64 getCenterFrequency() const final;
void setCenterFrequency(qint64 centerFrequency) final { (void) centerFrequency; }
std::time_t getStartingTimeStamp() const;
virtual bool handleMessage(const Message& message);
bool handleMessage(const Message& message) final;
virtual int webapiSettingsGet(
int webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiSettingsPutPatch(
int webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiReportGet(
int webapiReportGet(
SWGSDRangel::SWGDeviceReport& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiRunGet(
int webapiRunGet(
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiRun(
int webapiRun(
bool run,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
QString& errorMessage) final;
static void webapiFormatDeviceSettings(
SWGSDRangel::SWGDeviceSettings& response,
@ -258,7 +258,8 @@ public:
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
QRecursiveMutex m_mutex;
bool m_running;
RemoteOutputSettings m_settings;
uint64_t m_centerFrequency;
int m_sampleRate;
@ -283,7 +284,7 @@ private:
void applySettings(const RemoteOutputSettings& settings, const QList<QString>& settingsKeys, bool force = false);
void applyCenterFrequency();
void applySampleRate();
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response);
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response) const;
void analyzeApiReply(const QJsonObject& jsonObject, const QString& answer);
void queueLengthCompensation(

View File

@ -453,6 +453,11 @@ bool SoapySDROutput::start()
//
// Note: this is quite similar to the BladeRF2 start handling. The main difference is that the channel allocation (enabling) process is
// done in the thread object.
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_openSuccess)
{
@ -558,11 +563,13 @@ void SoapySDROutput::stop()
// channel then the FIFO reference is simply removed from the thread so that this FIFO will not be used anymore.
// In this case the channel is not closed (this is managed in the thread object) so that other channels can continue with the
// same configuration. The device continues streaming on this channel but the samples are set to all zeros.
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
int requestedChannel = m_deviceAPI->getDeviceItemIndex();
SoapySDROutputThread *soapySDROutputThread = findThread();
@ -648,9 +655,8 @@ void SoapySDROutput::stop()
soapySDROutputThread->setFifo(requestedChannel, nullptr); // remove FIFO
}
mutexLocker.unlock();
applySettings(m_settings, true); // re-apply forcibly to set sample rate with the new number of channels
m_running = false;
}
QByteArray SoapySDROutput::serialize() const

View File

@ -379,12 +379,16 @@ void USRPOutput::init()
bool USRPOutput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_deviceShared.m_deviceParams->getDevice()) {
return false;
}
if (m_running) { stop(); }
if (!acquireChannel()) {
return false;
}
@ -403,7 +407,14 @@ bool USRPOutput::start()
void USRPOutput::stop()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
qDebug("USRPOutput::stop");
m_running = false;
if (m_usrpOutputThread)
{
@ -413,7 +424,6 @@ void USRPOutput::stop()
}
m_deviceShared.m_thread = 0;
m_running = false;
releaseChannel();
}

View File

@ -265,6 +265,11 @@ bool XTRXOutput::start()
//
// Eventually it registers the FIFO in the thread. If the thread has to be started it enables the channels up to the number of channels
// allocated in the thread and starts the thread.
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_deviceShared.m_dev || !m_deviceShared.m_dev->getDevice())
{
@ -341,6 +346,8 @@ bool XTRXOutput::start()
xtrxOutputThread->setFifo(requestedChannel, &m_sampleSourceFifo);
xtrxOutputThread->setLog2Interpolation(requestedChannel, m_settings.m_log2SoftInterp);
m_running = true;
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
@ -351,7 +358,6 @@ bool XTRXOutput::start()
}
qDebug("XTRXOutput::start: started");
m_running = true;
return true;
}
@ -366,16 +372,18 @@ void XTRXOutput::stop()
// If the thread is currently managing both channels (MO mode) then we are removing one channel. Thus we must
// transition from MO to SO. This transition is handled by stopping the thread, deleting it and creating a new one
// managing a single channel.
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
int removedChannel = m_deviceAPI->getDeviceItemIndex(); // channel to remove
int requestedChannel = removedChannel ^ 1; // channel to keep (opposite channel)
XTRXOutputThread *xtrxOutputThread = findThread();
if (xtrxOutputThread == 0) { // no thread allocated
if (xtrxOutputThread == nullptr) { // no thread allocated
return;
}
@ -386,8 +394,8 @@ void XTRXOutput::stop()
qDebug("XTRXOutput::stop: SO mode. Just stop and delete the thread");
xtrxOutputThread->stopWork();
delete xtrxOutputThread;
m_XTRXOutputThread = 0;
m_deviceShared.m_thread = 0;
m_XTRXOutputThread = nullptr;
m_deviceShared.m_thread = nullptr;
// remove old thread address from buddies (reset in all buddies)
const std::vector<DeviceAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
@ -417,11 +425,10 @@ void XTRXOutput::stop()
((DeviceXTRXShared*) (*it)->getBuddySharedPtr())->m_sink->setThread(nullptr);
}
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
xtrxOutputThread->startWork();
}
m_running = false;
}
void XTRXOutput::suspendRxThread()

View File

@ -197,14 +197,14 @@ bool AirspyInput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_dev) {
return false;
}
if (m_running) {
return true;
}
if (!m_dev) {
return false;
}
m_airspyWorkerThread = new QThread();
m_airspyWorker = new AirspyWorker(m_dev, &m_sampleFifo);
m_airspyWorker->moveToThread(m_airspyWorkerThread);
@ -217,13 +217,13 @@ bool AirspyInput::start()
m_airspyWorker->setLog2Decimation(m_settings.m_log2Decim);
m_airspyWorker->setIQOrder(m_settings.m_iqOrder);
m_airspyWorker->setFcPos((int) m_settings.m_fcPos);
mutexLocker.unlock();
m_airspyWorkerThread->start();
m_running = true;
mutexLocker.unlock();
qDebug("AirspyInput::startInput: started");
applySettings(m_settings, QList<QString>(), true);
m_running = true;
return true;
}

View File

@ -141,7 +141,7 @@ public:
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
QRecursiveMutex m_mutex;
AirspySettings m_settings;
struct airspy_device* m_dev;
AirspyWorker* m_airspyWorker;

View File

@ -171,12 +171,12 @@ bool AirspyHFInput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_dev) {
return false;
if (m_running) {
return true;
}
if (m_running) {
stop();
if (!m_dev) {
return false;
}
m_airspyHFWorkerThread = new QThread();
@ -198,13 +198,13 @@ bool AirspyHFInput::start()
m_airspyHFWorker->setLog2Decimation(m_settings.m_log2Decim);
m_airspyHFWorker->setIQOrder(m_settings.m_iqOrder);
mutexLocker.unlock();
m_airspyHFWorkerThread->start();
m_running = true;
mutexLocker.unlock();
qDebug("AirspyHFInput::startInput: started");
applySettings(m_settings, QList<QString>(), true);
m_running = true;
return m_running;
}
@ -223,9 +223,15 @@ void AirspyHFInput::closeDevice()
void AirspyHFInput::stop()
{
qDebug("AirspyHFInput::stop");
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
qDebug("AirspyHFInput::stop");
m_running = false;
if (m_airspyHFWorkerThread)
{
m_airspyHFWorkerThread->quit();
@ -234,7 +240,6 @@ void AirspyHFInput::stop()
m_airspyHFWorker = nullptr;
}
m_running = false;
}
QByteArray AirspyHFInput::serialize() const

View File

@ -165,7 +165,7 @@ public:
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
QRecursiveMutex m_mutex;
AirspyHFSettings m_settings;
airspyhf_device_t* m_dev;
AirspyHFWorker* m_airspyHFWorker;

View File

@ -40,7 +40,7 @@ MESSAGE_CLASS_DEFINITION(Bladerf1Input::MsgStartStop, Message)
Bladerf1Input::Bladerf1Input(DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
m_settings(),
m_dev(0),
m_dev(nullptr),
m_bladerfThread(nullptr),
m_deviceDescription("BladeRFInput"),
m_running(false)
@ -70,11 +70,11 @@ Bladerf1Input::~Bladerf1Input()
delete m_networkManager;
if (m_running) {
stop();
Bladerf1Input::stop();
}
closeDevice();
m_deviceAPI->setBuddySharedPtr(0);
m_deviceAPI->setBuddySharedPtr(nullptr);
}
void Bladerf1Input::destroy()
@ -84,7 +84,7 @@ void Bladerf1Input::destroy()
bool Bladerf1Input::openDevice()
{
if (m_dev != 0)
if (m_dev != nullptr)
{
closeDevice();
}
@ -97,24 +97,24 @@ bool Bladerf1Input::openDevice()
return false;
}
if (m_deviceAPI->getSinkBuddies().size() > 0)
if (!m_deviceAPI->getSinkBuddies().empty())
{
DeviceAPI *sinkBuddy = m_deviceAPI->getSinkBuddies()[0];
DeviceBladeRF1Params *buddySharedParams = (DeviceBladeRF1Params *) sinkBuddy->getBuddySharedPtr();
const DeviceAPI *sinkBuddy = m_deviceAPI->getSinkBuddies()[0];
const DeviceBladeRF1Params *buddySharedParams = (DeviceBladeRF1Params *) sinkBuddy->getBuddySharedPtr();
if (buddySharedParams == 0)
if (buddySharedParams == nullptr)
{
qCritical("BladerfInput::openDevice: could not get shared parameters from buddy");
return false;
}
if (buddySharedParams->m_dev == 0) // device is not opened by buddy
if (buddySharedParams->m_dev == nullptr) // device is not opened by buddy
{
qCritical("BladerfInput::openDevice: could not get BladeRF handle from buddy");
return false;
}
m_sharedParams = *(buddySharedParams); // copy parameters from buddy
m_sharedParams = *buddySharedParams; // copy parameters from buddy
m_dev = m_sharedParams.m_dev; // get BladeRF handle
}
else
@ -128,7 +128,6 @@ bool Bladerf1Input::openDevice()
m_sharedParams.m_dev = m_dev;
}
// TODO: adjust USB transfer data according to sample rate
if ((res = bladerf_sync_config(m_dev, BLADERF_RX_X1, BLADERF_FORMAT_SC16_Q11, 64, 8192, 32, 10000)) < 0)
{
qCritical("BladerfInput::start: bladerf_sync_config with return code %d", res);
@ -151,7 +150,11 @@ void Bladerf1Input::init()
bool Bladerf1Input::start()
{
// QMutexLocker mutexLocker(&m_mutex);
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_dev)
{
@ -159,20 +162,17 @@ bool Bladerf1Input::start()
return false;
}
if (m_running) stop();
m_bladerfThread = new Bladerf1InputThread(m_dev, &m_sampleFifo);
m_bladerfThread->setLog2Decimation(m_settings.m_log2Decim);
m_bladerfThread->setFcPos((int) m_settings.m_fcPos);
m_bladerfThread->setIQOrder(m_settings.m_iqOrder);
m_bladerfThread->startWork();
m_running = true;
// mutexLocker.unlock();
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
qDebug("BladerfInput::startInput: started");
m_running = true;
return true;
}
@ -181,7 +181,7 @@ void Bladerf1Input::closeDevice()
{
int res;
if (m_dev == 0) { // was never open
if (m_dev == nullptr) { // was never open
return;
}
@ -190,23 +190,29 @@ void Bladerf1Input::closeDevice()
qCritical("BladerfInput::stop: bladerf_enable_module with return code %d", res);
}
if (m_deviceAPI->getSinkBuddies().size() == 0)
if (m_deviceAPI->getSinkBuddies().empty())
{
qDebug("BladerfInput::closeDevice: closing device since Tx side is not open");
if(m_dev != 0) // close BladeRF
if(m_dev != nullptr) // close BladeRF
{
bladerf_close(m_dev);
}
}
m_sharedParams.m_dev = 0;
m_dev = 0;
m_sharedParams.m_dev = nullptr;
m_dev = nullptr;
}
void Bladerf1Input::stop()
{
// QMutexLocker mutexLocker(&m_mutex);
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
if(m_bladerfThread)
{
@ -215,7 +221,6 @@ void Bladerf1Input::stop()
m_bladerfThread = nullptr;
}
m_running = false;
}
QByteArray Bladerf1Input::serialize() const
@ -280,7 +285,7 @@ bool Bladerf1Input::handleMessage(const Message& message)
{
if (MsgConfigureBladerf1::match(message))
{
MsgConfigureBladerf1& conf = (MsgConfigureBladerf1&) message;
auto& conf = (const MsgConfigureBladerf1&) message;
qDebug() << "Bladerf1Input::handleMessage: MsgConfigureBladerf1";
if (!applySettings(conf.getSettings(), conf.getSettingsKeys(), conf.getForce())) {
@ -291,7 +296,7 @@ bool Bladerf1Input::handleMessage(const Message& message)
}
else if (MsgStartStop::match(message))
{
MsgStartStop& cmd = (MsgStartStop&) message;
auto& cmd = (const MsgStartStop&) message;
qDebug() << "BladerfInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
if (cmd.getStartStop())
@ -320,7 +325,6 @@ bool Bladerf1Input::handleMessage(const Message& message)
bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const QList<QString>& settingsKeys, bool force)
{
bool forwardChange = false;
// QMutexLocker mutexLocker(&m_mutex);
qDebug() << "BladerfInput::applySettings: force: " << force << settings.getDebugString(settingsKeys, force);
@ -330,9 +334,7 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
m_deviceAPI->configureCorrections(settings.m_dcBlock, settings.m_iqCorrection);
}
if (settingsKeys.contains("lnaGain") || force)
{
if (m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("lnaGain") || force))
{
if(bladerf_set_lna_gain(m_dev, getLnaGain(settings.m_lnaGain)) != 0) {
qDebug("BladerfInput::applySettings: bladerf_set_lna_gain() failed");
@ -340,11 +342,8 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
qDebug() << "BladerfInput::applySettings: LNA gain set to " << getLnaGain(settings.m_lnaGain);
}
}
}
if (settingsKeys.contains("vga1") || force)
{
if (m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("vga1") || force))
{
if(bladerf_set_rxvga1(m_dev, settings.m_vga1) != 0) {
qDebug("BladerfInput::applySettings: bladerf_set_rxvga1() failed");
@ -352,11 +351,8 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
qDebug() << "BladerfInput::applySettings: VGA1 gain set to " << settings.m_vga1;
}
}
}
if (settingsKeys.contains("vga2") || force)
{
if(m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("vga2") || force))
{
if(bladerf_set_rxvga2(m_dev, settings.m_vga2) != 0) {
qDebug("BladerfInput::applySettings: bladerf_set_rxvga2() failed");
@ -364,19 +360,16 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
qDebug() << "BladerfInput::applySettings: VGA2 gain set to " << settings.m_vga2;
}
}
}
if (settingsKeys.contains("xb200") || force)
{
if (m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("xb200") || force))
{
bool changeSettings;
if (m_deviceAPI->getSinkBuddies().size() > 0)
if (!m_deviceAPI->getSinkBuddies().empty())
{
DeviceAPI *buddy = m_deviceAPI->getSinkBuddies()[0];
if (buddy->getDeviceSinkEngine()->state() == DSPDeviceSinkEngine::StRunning) { // Tx side running
if (buddy->getDeviceSinkEngine()->state() == DSPDeviceSinkEngine::State::StRunning) { // Tx side running
changeSettings = false;
} else {
changeSettings = true;
@ -409,11 +402,8 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
m_sharedParams.m_xb200Attached = settings.m_xb200;
}
}
}
if (settingsKeys.contains("xb200Path") || force)
{
if (m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("xb200Path") || force))
{
if(bladerf_xb200_set_path(m_dev, BLADERF_MODULE_RX, settings.m_xb200Path) != 0) {
qDebug("BladerfInput::applySettings: bladerf_xb200_set_path(BLADERF_MODULE_RX) failed");
@ -421,11 +411,8 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
qDebug() << "BladerfInput::applySettings: set xb200 path to " << settings.m_xb200Path;
}
}
}
if (settingsKeys.contains("xb200Filter") || force)
{
if (m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("xb200Filter") || force))
{
if(bladerf_xb200_set_filterbank(m_dev, BLADERF_MODULE_RX, settings.m_xb200Filter) != 0) {
qDebug("BladerfInput::applySettings: bladerf_xb200_set_filterbank(BLADERF_MODULE_RX) failed");
@ -433,13 +420,12 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
qDebug() << "BladerfInput::applySettings: set xb200 filter to " << settings.m_xb200Filter;
}
}
}
if (settingsKeys.contains("devSampleRate") || force)
{
forwardChange = true;
if (m_dev != 0)
if (m_dev != nullptr)
{
unsigned int actualSamplerate;
@ -451,9 +437,7 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
}
}
if (settingsKeys.contains("bandwidth") || force)
{
if(m_dev != 0)
if ((m_dev != nullptr) && (settingsKeys.contains("bandwidth") || force))
{
unsigned int actualBandwidth;
@ -463,16 +447,12 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
qDebug() << "BladerfInput::applySettings: bladerf_set_bandwidth(BLADERF_MODULE_RX) actual bandwidth is " << actualBandwidth;
}
}
}
if (settingsKeys.contains("fcPos") || force)
{
if (m_bladerfThread)
if (m_bladerfThread && (settingsKeys.contains("fcPos") || force))
{
m_bladerfThread->setFcPos((int) settings.m_fcPos);
qDebug() << "BladerfInput::applySettings: set fc pos (enum) to " << (int) settings.m_fcPos;
}
}
if (settingsKeys.contains("log2Decim") || force)
{
@ -485,12 +465,10 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
}
}
if (settingsKeys.contains("iqOrder") || force)
if (m_bladerfThread && (settingsKeys.contains("iqOrder") || force))
{
if (m_bladerfThread) {
m_bladerfThread->setIQOrder(settings.m_iqOrder);
}
}
if (settingsKeys.contains("centerFrequency")
|| settingsKeys.contains("log2Decim")
@ -508,7 +486,7 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
forwardChange = true;
if (m_dev != 0)
if (m_dev != nullptr)
{
if (bladerf_set_frequency( m_dev, BLADERF_MODULE_RX, deviceCenterFrequency ) != 0) {
qWarning("BladerfInput::applySettings: bladerf_set_frequency(%lld) failed", settings.m_centerFrequency);
@ -521,7 +499,7 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
if (forwardChange)
{
int sampleRate = settings.m_devSampleRate/(1<<settings.m_log2Decim);
DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, settings.m_centerFrequency);
auto *notif = new DSPSignalNotification(sampleRate, settings.m_centerFrequency);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
}
@ -543,7 +521,7 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, const Q
return true;
}
bladerf_lna_gain Bladerf1Input::getLnaGain(int lnaGain)
bladerf_lna_gain Bladerf1Input::getLnaGain(int lnaGain) const
{
if (lnaGain == 2) {
return BLADERF_LNA_GAIN_MAX;
@ -650,7 +628,7 @@ void Bladerf1Input::webapiUpdateDeviceSettings(
settings.m_fcPos = static_cast<BladeRF1InputSettings::fcPos_t>(response.getBladeRf1InputSettings()->getFcPos());
}
if (deviceSettingsKeys.contains("xb200")) {
settings.m_xb200 = response.getBladeRf1InputSettings()->getXb200() == 0 ? 0 : 1;
settings.m_xb200 = response.getBladeRf1InputSettings()->getXb200() == 0 ? false : true;
}
if (deviceSettingsKeys.contains("xb200Path")) {
settings.m_xb200Path = static_cast<bladerf_xb200_path>(response.getBladeRf1InputSettings()->getXb200Path());
@ -671,10 +649,10 @@ void Bladerf1Input::webapiUpdateDeviceSettings(
settings.m_reverseAPIAddress = *response.getBladeRf1InputSettings()->getReverseApiAddress();
}
if (deviceSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getBladeRf1InputSettings()->getReverseApiPort();
settings.m_reverseAPIPort = (uint16_t) response.getBladeRf1InputSettings()->getReverseApiPort();
}
if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getBladeRf1InputSettings()->getReverseApiDeviceIndex();
settings.m_reverseAPIDeviceIndex = (uint16_t) response.getBladeRf1InputSettings()->getReverseApiDeviceIndex();
}
}
@ -708,7 +686,7 @@ int Bladerf1Input::webapiRun(
void Bladerf1Input::webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const BladeRF1InputSettings& settings, bool force)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
auto *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(0); // single Rx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("BladeRF1"));
@ -767,8 +745,8 @@ void Bladerf1Input::webapiReverseSendSettings(const QList<QString>& deviceSettin
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
@ -781,7 +759,7 @@ void Bladerf1Input::webapiReverseSendSettings(const QList<QString>& deviceSettin
void Bladerf1Input::webapiReverseSendStartStop(bool start)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
auto *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(0); // single Rx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("BladeRF1"));
@ -793,8 +771,8 @@ void Bladerf1Input::webapiReverseSendStartStop(bool start)
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
QNetworkReply *reply;
@ -809,7 +787,7 @@ void Bladerf1Input::webapiReverseSendStartStop(bool start)
delete swgDeviceSettings;
}
void Bladerf1Input::networkManagerFinished(QNetworkReply *reply)
void Bladerf1Input::networkManagerFinished(QNetworkReply *reply) const
{
QNetworkReply::NetworkError replyError = reply->error();

View File

@ -76,53 +76,53 @@ public:
return new MsgStartStop(startStop);
}
protected:
private:
bool m_startStop;
MsgStartStop(bool startStop) :
explicit MsgStartStop(bool startStop) :
Message(),
m_startStop(startStop)
{ }
};
Bladerf1Input(DeviceAPI *deviceAPI);
virtual ~Bladerf1Input();
virtual void destroy();
explicit Bladerf1Input(DeviceAPI *deviceAPI);
~Bladerf1Input() final;
void destroy() final;
virtual void init();
virtual bool start();
virtual void stop();
void init() final;
bool start() final;
void stop() final;
virtual QByteArray serialize() const;
virtual bool deserialize(const QByteArray& data);
QByteArray serialize() const final;
bool deserialize(const QByteArray& data) final;
virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; }
virtual const QString& getDeviceDescription() const;
virtual int getSampleRate() const;
virtual void setSampleRate(int sampleRate) { (void) sampleRate; }
virtual quint64 getCenterFrequency() const;
virtual void setCenterFrequency(qint64 centerFrequency);
void setMessageQueueToGUI(MessageQueue *queue) final { m_guiMessageQueue = queue; }
const QString& getDeviceDescription() const final;
int getSampleRate() const final;
void setSampleRate(int sampleRate) final { (void) sampleRate; }
quint64 getCenterFrequency() const final;
void setCenterFrequency(qint64 centerFrequency) final;
virtual bool handleMessage(const Message& message);
bool handleMessage(const Message& message) final;
virtual int webapiSettingsGet(
int webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiSettingsPutPatch(
int webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiRunGet(
int webapiRunGet(
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiRun(
int webapiRun(
bool run,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
QString& errorMessage) final;
static void webapiFormatDeviceSettings(
SWGSDRangel::SWGDeviceSettings& response,
@ -135,7 +135,7 @@ public:
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
QRecursiveMutex m_mutex;
BladeRF1InputSettings m_settings;
struct bladerf* m_dev;
Bladerf1InputThread* m_bladerfThread;
@ -148,12 +148,12 @@ private:
bool openDevice();
void closeDevice();
bool applySettings(const BladeRF1InputSettings& settings, const QList<QString>& settingsKeys, bool force);
bladerf_lna_gain getLnaGain(int lnaGain);
bladerf_lna_gain getLnaGain(int lnaGain) const;
void webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const BladeRF1InputSettings& settings, bool force);
void webapiReverseSendStartStop(bool start);
private slots:
void networkManagerFinished(QNetworkReply *reply);
void networkManagerFinished(QNetworkReply *reply) const;
};
#endif // INCLUDE_BLADERFINPUT_H

View File

@ -290,6 +290,11 @@ bool BladeRF2Input::start()
//
// Eventually it registers the FIFO in the thread. If the thread has to be started it enables the channels up to the number of channels
// allocated in the thread and starts the thread.
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_deviceShared.m_dev)
{
@ -383,10 +388,11 @@ bool BladeRF2Input::start()
bladerf2InputThread->startWork();
}
m_running = true;
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
qDebug("BladeRF2Input::start: started");
m_running = true;
return true;
}
@ -408,6 +414,7 @@ void BladeRF2Input::stop()
// anymore. In this case the channel is not closed (disabled) so that other channels can continue with the
// same configuration. The device continues streaming on this channel but the samples are simply dropped (by
// removing FIFO reference).
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
@ -420,6 +427,7 @@ void BladeRF2Input::stop()
return;
}
m_running = false;
int nbOriginalChannels = bladerf2InputThread->getNbChannels();
if (nbOriginalChannels == 1) // SI mode => just stop and delete the thread
@ -500,8 +508,6 @@ void BladeRF2Input::stop()
qDebug("BladeRF2Input::stop: MI mode. Not changing MI configuration. Just remove FIFO reference");
bladerf2InputThread->setFifo(requestedChannel, 0); // remove FIFO
}
m_running = false;
}
QByteArray BladeRF2Input::serialize() const

View File

@ -121,15 +121,18 @@ void FCDProInput::init()
bool FCDProInput::start()
{
qDebug() << "FCDProInput::start";
// QMutexLocker mutexLocker(&m_mutex);
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_dev) {
return false;
}
if (m_running) stop();
qDebug() << "FCDProInput::start";
/* Apply settings before streaming to avoid bus contention;
* there is very little spare bandwidth on a full speed USB device.
@ -149,12 +152,12 @@ bool FCDProInput::start()
m_FCDThread->setFcPos(m_settings.m_fcPos);
m_FCDThread->setIQOrder(m_settings.m_iqOrder);
m_FCDThread->startWork();
m_running = true;
// mutexLocker.unlock();
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
qDebug("FCDProInput::started");
m_running = true;
return true;
}
@ -204,7 +207,13 @@ void FCDProInput::closeFCDAudio()
void FCDProInput::stop()
{
// QMutexLocker mutexLocker(&m_mutex);
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
if (m_FCDThread)
{
@ -213,8 +222,6 @@ void FCDProInput::stop()
delete m_FCDThread;
m_FCDThread = nullptr;
}
m_running = false;
}
QByteArray FCDProInput::serialize() const

View File

@ -121,14 +121,14 @@ void FCDProPlusInput::init()
bool FCDProPlusInput::start()
{
// QMutexLocker mutexLocker(&m_mutex);
QMutexLocker mutexLocker(&m_mutex);
if (!m_dev) {
return false;
}
if (m_running) {
stop();
return true;
}
qDebug() << "FCDProPlusInput::start";
@ -151,12 +151,12 @@ bool FCDProPlusInput::start()
m_FCDThread->setFcPos(m_settings.m_fcPos);
m_FCDThread->setIQOrder(m_settings.m_iqOrder);
m_FCDThread->startWork();
m_running = true;
// mutexLocker.unlock();
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
qDebug("FCDProPlusInput::started");
m_running = true;
return true;
}
@ -208,6 +208,12 @@ void FCDProPlusInput::stop()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
if (m_FCDThread)
{
m_FCDThread->stopWork();
@ -215,8 +221,6 @@ void FCDProPlusInput::stop()
delete m_FCDThread;
m_FCDThread = nullptr;
}
m_running = false;
}
QByteArray FCDProPlusInput::serialize() const

View File

@ -142,29 +142,29 @@ void HackRFInput::init()
bool HackRFInput::start()
{
// QMutexLocker mutexLocker(&m_mutex);
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_dev) {
return false;
}
if (m_running) {
stop();
}
m_hackRFThread = new HackRFInputThread(m_dev, &m_sampleFifo);
// mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
m_hackRFThread->setSamplerate(m_settings.m_devSampleRate);
m_hackRFThread->setLog2Decimation(m_settings.m_log2Decim);
m_hackRFThread->setFcPos((int) m_settings.m_fcPos);
m_hackRFThread->setIQOrder(m_settings.m_iqOrder);
m_hackRFThread->startWork();
m_running = true;
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
qDebug("HackRFInput::startInput: started");
m_running = true;
return true;
}
@ -188,8 +188,14 @@ void HackRFInput::closeDevice()
void HackRFInput::stop()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
qDebug("HackRFInput::stop");
// QMutexLocker mutexLocker(&m_mutex);
m_running = false;
if (m_hackRFThread)
{
@ -197,8 +203,6 @@ void HackRFInput::stop()
delete m_hackRFThread;
m_hackRFThread = nullptr;
}
m_running = false;
}
QByteArray HackRFInput::serialize() const
@ -349,7 +353,7 @@ void HackRFInput::setDeviceCenterFrequency(quint64 freq_hz, int loPpmTenths)
bool HackRFInput::applySettings(const HackRFInputSettings& settings, const QList<QString>& settingsKeys, bool force)
{
// QMutexLocker mutexLocker(&m_mutex);
QMutexLocker mutexLocker(&m_mutex);
qDebug() << "HackRFInput::applySettings: forcE: " << force << settings.getDebugString(settingsKeys, force);
bool forwardChange = false;
hackrf_error rc;

View File

@ -153,7 +153,7 @@ public:
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
QRecursiveMutex m_mutex;
HackRFInputSettings m_settings;
struct hackrf_device* m_dev;
HackRFInputThread* m_hackRFThread;

View File

@ -409,14 +409,17 @@ void LimeSDRInput::init()
bool LimeSDRInput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_deviceShared.m_deviceParams->getDevice()) {
return false;
}
if (m_running) { stop(); }
if (!acquireChannel())
{
if (!acquireChannel()) {
return false;
}
@ -425,21 +428,28 @@ bool LimeSDRInput::start()
m_limeSDRInputThread = new LimeSDRInputThread(&m_streamId, &m_sampleFifo, &m_replayBuffer);
qDebug("LimeSDRInput::start: thread created");
applySettings(m_settings, QList<QString>(), true);
m_limeSDRInputThread->setLog2Decimation(m_settings.m_log2SoftDecim);
m_limeSDRInputThread->setIQOrder(m_settings.m_iqOrder);
m_limeSDRInputThread->startWork();
m_deviceShared.m_thread = m_limeSDRInputThread;
m_running = true;
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
return true;
}
void LimeSDRInput::stop()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
qDebug("LimeSDRInput::stop");
m_running = false;
if (m_limeSDRInputThread)
{
@ -449,7 +459,6 @@ void LimeSDRInput::stop()
}
m_deviceShared.m_thread = 0;
m_running = false;
releaseChannel();
}
@ -803,7 +812,7 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, const QLi
bool doLPCalibration = false;
double clockGenFreq = 0.0;
// QMutexLocker mutexLocker(&m_mutex);
QMutexLocker mutexLocker(&m_mutex);
qint64 deviceCenterFrequency = settings.m_centerFrequency;
deviceCenterFrequency -= settings.m_transverterMode ? settings.m_transverterDeltaFrequency : 0;

View File

@ -290,7 +290,7 @@ public:
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
QRecursiveMutex m_mutex;
LimeSDRInputSettings m_settings;
LimeSDRInputThread* m_limeSDRInputThread;
QString m_deviceDescription;

View File

@ -102,35 +102,45 @@ void PlutoSDRInput::init()
bool PlutoSDRInput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_deviceShared.m_deviceParams->getBox())
{
qCritical("PlutoSDRInput::start: device not open");
return false;
}
if (m_running) {
stop();
}
// start / stop streaming is done in the thread.
m_plutoSDRInputThread = new PlutoSDRInputThread(PLUTOSDR_BLOCKSIZE_SAMPLES, m_deviceShared.m_deviceParams->getBox(), &m_sampleFifo);
qDebug("PlutoSDRInput::start: thread created");
applySettings(m_settings, QList<QString>(), true);
m_plutoSDRInputThread->setLog2Decimation(m_settings.m_log2Decim);
m_plutoSDRInputThread->setIQOrder(m_settings.m_iqOrder);
m_plutoSDRInputThread->startWork();
m_deviceShared.m_thread = m_plutoSDRInputThread;
m_running = true;
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
return true;
}
void PlutoSDRInput::stop()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
if (m_plutoSDRInputThread)
{
m_plutoSDRInputThread->stopWork();
@ -139,7 +149,6 @@ void PlutoSDRInput::stop()
}
m_deviceShared.m_thread = nullptr;
m_running = false;
}
QByteArray PlutoSDRInput::serialize() const

View File

@ -78,6 +78,7 @@ RTLSDRInput::RTLSDRInput(DeviceAPI *deviceAPI) :
RTLSDRInput::~RTLSDRInput()
{
qDebug("RTLSDRInput::~RTLSDRInput");
QObject::disconnect(
m_networkManager,
&QNetworkAccessManager::finished,
@ -91,6 +92,7 @@ RTLSDRInput::~RTLSDRInput()
}
closeDevice();
qDebug("RTLSDRInput::~RTLSDRInput: end");
}
void RTLSDRInput::destroy()
@ -231,11 +233,15 @@ bool RTLSDRInput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_dev) {
return false;
}
if (m_running) stop();
qDebug("RTLSDRInput::start");
m_rtlSDRThread = new RTLSDRThread(m_dev, &m_sampleFifo, &m_replayBuffer);
m_rtlSDRThread->setSamplerate(m_settings.m_devSampleRate);
@ -243,11 +249,11 @@ bool RTLSDRInput::start()
m_rtlSDRThread->setFcPos((int) m_settings.m_fcPos);
m_rtlSDRThread->setIQOrder(m_settings.m_iqOrder);
m_rtlSDRThread->startWork();
m_running = true;
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
m_running = true;
return true;
}
@ -267,6 +273,12 @@ void RTLSDRInput::stop()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
qDebug("RTLSDRInput::stop");
if (m_rtlSDRThread)
{
m_rtlSDRThread->stopWork();

View File

@ -149,15 +149,17 @@ bool SDRPlayInput::openDevice()
bool SDRPlayInput::start()
{
// QMutexLocker mutexLocker(&m_mutex);
int res;
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_dev) {
return false;
}
if (m_running) stop();
int res;
char s12FormatString[] = "336_S16";
if ((res = mirisdr_set_sample_format(m_dev, s12FormatString))) // sample format S12
@ -197,12 +199,11 @@ bool SDRPlayInput::start()
m_sdrPlayThread->setFcPos((int) m_settings.m_fcPos);
m_sdrPlayThread->setIQOrder(m_settings.m_iqOrder);
m_sdrPlayThread->startWork();
// mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true, true);
m_running = true;
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true, true);
return true;
}
@ -224,7 +225,13 @@ void SDRPlayInput::init()
void SDRPlayInput::stop()
{
// QMutexLocker mutexLocker(&m_mutex);
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
if(m_sdrPlayThread)
{
@ -232,8 +239,6 @@ void SDRPlayInput::stop()
delete m_sdrPlayThread;
m_sdrPlayThread = nullptr;
}
m_running = false;
}
QByteArray SDRPlayInput::serialize() const

View File

@ -173,7 +173,7 @@ public:
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
QRecursiveMutex m_mutex;
SDRPlayVariant m_variant;
SDRPlaySettings m_settings;
mirisdr_dev_t* m_dev;

View File

@ -147,20 +147,25 @@ bool SDRPlayV3Input::openDevice()
bool SDRPlayV3Input::start()
{
qDebug() << "SDRPlayV3Input::start";
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_dev) {
return false;
}
if (m_running) stop();
qDebug() << "SDRPlayV3Input::start";
m_sdrPlayThread = new SDRPlayV3Thread(m_dev, &m_sampleFifo, &m_replayBuffer);
m_sdrPlayThread->setLog2Decimation(m_settings.m_log2Decim);
m_sdrPlayThread->setFcPos((int) m_settings.m_fcPos);
m_sdrPlayThread->startWork();
m_running = m_sdrPlayThread->isRunning();
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true, true);
return true;
@ -184,17 +189,21 @@ void SDRPlayV3Input::init()
void SDRPlayV3Input::stop()
{
qDebug() << "SDRPlayV3Input::stop";
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
qDebug() << "SDRPlayV3Input::stop";
m_running = false;
if(m_sdrPlayThread)
{
m_sdrPlayThread->stopWork();
delete m_sdrPlayThread;
m_sdrPlayThread = nullptr;
}
m_running = false;
}
QByteArray SDRPlayV3Input::serialize() const

View File

@ -158,7 +158,7 @@ public:
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
QRecursiveMutex m_mutex;
SDRPlayV3Settings m_settings;
sdrplay_api_DeviceT m_devs[SDRPLAY_MAX_DEVICES];
sdrplay_api_DeviceT* m_dev;

View File

@ -62,19 +62,7 @@ MESSAGE_CLASS_DEFINITION(SigMFFileInput::MsgReportTotalSamplesCheck, Message)
SigMFFileInput::SigMFFileInput(DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
m_settings(),
m_trackMode(false),
m_currentTrackIndex(0),
m_recordOpen(false),
m_crcAvailable(false),
m_crcOK(false),
m_recordLengthOK(false),
m_fileInputWorker(nullptr),
m_deviceDescription("SigMFFileInput"),
m_sampleRate(48000),
m_sampleBytes(1),
m_centerFrequency(0),
m_recordLength(0),
m_startingTimeStamp(0)
m_deviceDescription("SigMFFileInput")
{
m_sampleFifo.setLabel(m_deviceDescription);
m_deviceAPI->setNbSourceStreams(1);
@ -103,7 +91,7 @@ SigMFFileInput::~SigMFFileInput()
);
delete m_networkManager;
stop();
SigMFFileInput::stop();
}
void SigMFFileInput::destroy()
@ -155,8 +143,8 @@ bool SigMFFileInput::openFileStreams(const QString& fileName)
extractCaptures(&metaRecord);
m_metaInfo.m_totalTimeMs = m_captures.back().m_cumulativeTime + ((m_captures.back().m_length * 1000)/m_captures.back().m_sampleRate);
uint64_t centerFrequency = (m_captures.size() > 0) ? m_captures.at(0).m_centerFrequency : 0;
DSPSignalNotification *notif = new DSPSignalNotification(m_metaInfo.m_coreSampleRate, centerFrequency);
uint64_t centerFrequency = (!m_captures.empty()) ? m_captures.at(0).m_centerFrequency : 0;
auto *notif = new DSPSignalNotification((int) m_metaInfo.m_coreSampleRate, centerFrequency);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
if (getMessageQueueToGUI())
@ -243,15 +231,14 @@ void SigMFFileInput::extractMeta(
m_metaInfo.m_arch = QString::fromStdString(metaRecord->global.access<sdrangel::GlobalT>().arch);
m_metaInfo.m_os = QString::fromStdString(metaRecord->global.access<sdrangel::GlobalT>().os);
// lists
m_metaInfo.m_nbCaptures = metaRecord->captures.size();
m_metaInfo.m_nbAnnotations = metaRecord->annotations.size();
m_metaInfo.m_nbCaptures = (unsigned int) metaRecord->captures.size();
m_metaInfo.m_nbAnnotations = (unsigned int) metaRecord->annotations.size();
// correct sample bits if sdrangel
if (m_metaInfo.m_sdrAngelVersion.size() > 0)
if ((m_metaInfo.m_sdrAngelVersion.size() > 0)
&& (m_metaInfo.m_dataType.m_sampleBits == 32))
{
if (m_metaInfo.m_dataType.m_sampleBits == 32) {
m_metaInfo.m_dataType.m_sampleBits = 24;
}
}
// negative sample rate means inversion
m_metaInfo.m_dataType.m_swapIQ = m_metaInfo.m_coreSampleRate < 0;
if (m_metaInfo.m_coreSampleRate < 0) {
@ -269,8 +256,7 @@ void SigMFFileInput::extractCaptures(
std::regex datetime_reg("(\\d{4})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d):(\\d\\d)(\\.\\d+)?(([+-]\\d\\d:\\d\\d)|Z)?");
std::smatch datetime_match;
sigmf::SigMFVector<sigmf::Capture<core::DescrT, sdrangel::DescrT>>::iterator it =
metaRecord->captures.begin();
auto it = metaRecord->captures.begin();
uint64_t lastSampleStart = 0;
unsigned int i = 0;
uint64_t cumulativeTime = 0;
@ -278,7 +264,7 @@ void SigMFFileInput::extractCaptures(
for (; it != metaRecord->captures.end(); ++it, i++)
{
m_captures.push_back(SigMFFileCapture());
m_captures.back().m_centerFrequency = it->get<core::DescrT>().frequency;
m_captures.back().m_centerFrequency = (uint64_t) it->get<core::DescrT>().frequency;
m_captures.back().m_sampleStart = it->get<core::DescrT>().sample_start;
m_captureStarts.push_back(m_captures.back().m_sampleStart);
m_captures.back().m_cumulativeTime = cumulativeTime;
@ -286,7 +272,7 @@ void SigMFFileInput::extractCaptures(
double globalSampleRate = metaRecord->global.access<core::GlobalT>().sample_rate;
if (sdrangelSampleRate == 0) {
m_captures.back().m_sampleRate = globalSampleRate < 0 ? -globalSampleRate : globalSampleRate;
m_captures.back().m_sampleRate = (unsigned int) (globalSampleRate < 0 ? -globalSampleRate : globalSampleRate);
} else {
m_captures.back().m_sampleRate = sdrangelSampleRate;
}
@ -325,7 +311,7 @@ void SigMFFileInput::extractCaptures(
dateTime = QDateTime::currentDateTimeUtc();
}
double seconds = dateTime.toSecsSinceEpoch();
auto seconds = (double) dateTime.toSecsSinceEpoch();
// the subsecond part can be milli (strict ISO-8601) or micro or nano (RFC-3339). This will take any width
if (datetime_match.size() > 7)
{
@ -334,13 +320,13 @@ void SigMFFileInput::extractCaptures(
double fractionalSecs = boost::lexical_cast<double>(datetime_match[7]);
seconds += fractionalSecs;
}
catch (const boost::bad_lexical_cast &e)
catch (const boost::bad_lexical_cast&)
{
qDebug("SigMFFileInput::extractCaptures: invalid fractional seconds");
}
}
m_captures.back().m_tsms = seconds * 1000.0;
m_captures.back().m_tsms = (uint64_t) (seconds * 1000.0);
}
m_captures.back().m_length = it->get<core::DescrT>().length;
@ -389,7 +375,7 @@ void SigMFFileInput::analyzeDataType(const std::string& dataTypeString, SigMFFil
{
dataType.m_sampleBits = boost::lexical_cast<int>(dataType_match[3]);
}
catch(const boost::bad_lexical_cast &e)
catch(const boost::bad_lexical_cast&)
{
qDebug("SigMFFileInput::analyzeDataType: invalid sample bits. Assume 32");
dataType.m_sampleBits = 32;
@ -413,7 +399,7 @@ uint64_t SigMFFileInput::getTrackSampleStart(unsigned int trackIndex)
int SigMFFileInput::getTrackIndex(uint64_t sampleIndex)
{
auto it = std::upper_bound(m_captureStarts.begin(), m_captureStarts.end(), sampleIndex);
return (it - m_captureStarts.begin()) - 1;
return (int) ((it - m_captureStarts.begin()) - 1);
}
void SigMFFileInput::seekFileStream(uint64_t sampleIndex)
@ -440,19 +426,24 @@ void SigMFFileInput::seekFileMillis(int seekMillis)
void SigMFFileInput::init()
{
DSPSignalNotification *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
auto *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
}
bool SigMFFileInput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_dataStream.is_open())
{
qWarning("SigMFFileInput::start: file not open. not starting");
return false;
}
QMutexLocker mutexLocker(&m_mutex);
qDebug() << "SigMFFileInput::start";
if (m_dataStream.tellg() != (std::streampos) 0) {
@ -472,6 +463,7 @@ bool SigMFFileInput::start()
m_fileInputWorker->setTrackIndex(0);
m_fileInputWorker->moveToThread(&m_fileInputWorkerThread);
m_deviceDescription = "SigMFFileInput";
m_running = true;
mutexLocker.unlock();
qDebug("SigMFFileInput::startInput: started");
@ -486,9 +478,15 @@ bool SigMFFileInput::start()
void SigMFFileInput::stop()
{
qDebug() << "SigMFFileInput::stop";
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
qDebug() << "SigMFFileInput::stop";
m_running = false;
if (m_fileInputWorker)
{
stopWorker();
@ -583,13 +581,13 @@ bool SigMFFileInput::handleMessage(const Message& message)
{
if (MsgConfigureSigMFFileInput::match(message))
{
MsgConfigureSigMFFileInput& conf = (MsgConfigureSigMFFileInput&) message;
auto& conf = (const MsgConfigureSigMFFileInput&) message;
applySettings(conf.getSettings(), conf.getSettingsKeys(), conf.getForce());
return true;
}
else if (MsgConfigureTrackIndex::match(message))
{
MsgConfigureTrackIndex& conf = (MsgConfigureTrackIndex&) message;
auto& conf = (const MsgConfigureTrackIndex&) message;
m_currentTrackIndex = conf.getTrackIndex();
qDebug("SigMFFileInput::handleMessage MsgConfigureTrackIndex: m_currentTrackIndex: %d", m_currentTrackIndex);
seekTrackMillis(0);
@ -618,7 +616,7 @@ bool SigMFFileInput::handleMessage(const Message& message)
}
else if (MsgConfigureTrackWork::match(message))
{
MsgConfigureTrackWork& conf = (MsgConfigureTrackWork&) message;
auto& conf = (const MsgConfigureTrackWork&) message;
bool working = conf.isWorking();
m_trackMode = true;
@ -640,7 +638,7 @@ bool SigMFFileInput::handleMessage(const Message& message)
}
else if (MsgConfigureTrackSeek::match(message))
{
MsgConfigureTrackSeek& conf = (MsgConfigureTrackSeek&) message;
auto& conf = (const MsgConfigureTrackSeek&) message;
int seekMillis = conf.getMillis();
seekTrackMillis(seekMillis);
@ -664,7 +662,7 @@ bool SigMFFileInput::handleMessage(const Message& message)
}
else if (MsgConfigureFileSeek::match(message))
{
MsgConfigureFileSeek& conf = (MsgConfigureFileSeek&) message;
auto& conf = (const MsgConfigureFileSeek&) message;
int seekMillis = conf.getMillis();
seekFileStream(seekMillis);
uint64_t sampleCount = (m_metaInfo.m_totalSamples*seekMillis)/1000UL;
@ -690,7 +688,7 @@ bool SigMFFileInput::handleMessage(const Message& message)
}
else if (MsgConfigureFileWork::match(message))
{
MsgConfigureFileWork& conf = (MsgConfigureFileWork&) message;
auto& conf = (const MsgConfigureFileWork&) message;
bool working = conf.isWorking();
m_trackMode = false;
@ -711,9 +709,7 @@ bool SigMFFileInput::handleMessage(const Message& message)
}
else if (MsgConfigureFileInputStreamTiming::match(message))
{
if (m_fileInputWorker)
{
if (getMessageQueueToGUI())
if (m_fileInputWorker && getMessageQueueToGUI())
{
quint64 totalSamplesCount = m_fileInputWorker->getSamplesCount();
quint64 trackSamplesCount = totalSamplesCount - m_captures[m_currentTrackIndex].m_sampleStart;
@ -725,13 +721,12 @@ bool SigMFFileInput::handleMessage(const Message& message)
);
getMessageQueueToGUI()->push(report);
}
}
return true;
}
else if (MsgStartStop::match(message))
{
MsgStartStop& cmd = (MsgStartStop&) message;
auto& cmd = (const MsgStartStop&) message;
qDebug() << "FileInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
if (cmd.getStartStop())
@ -785,7 +780,7 @@ bool SigMFFileInput::handleMessage(const Message& message)
}
else if (SigMFFileInputWorker::MsgReportTrackChange::match(message))
{
SigMFFileInputWorker::MsgReportTrackChange& report = (SigMFFileInputWorker::MsgReportTrackChange&) message;
auto& report = (const SigMFFileInputWorker::MsgReportTrackChange&) message;
m_currentTrackIndex = report.getTrackIndex();
qDebug("SigMFFileInput::handleMessage MsgReportTrackChange: m_currentTrackIndex: %d", m_currentTrackIndex);
int sampleRate = m_captures.at(m_currentTrackIndex).m_sampleRate;
@ -793,7 +788,7 @@ bool SigMFFileInput::handleMessage(const Message& message)
if ((m_sampleRate != sampleRate) || (m_centerFrequency != centerFrequency))
{
DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, centerFrequency);
auto *notif = new DSPSignalNotification(sampleRate, centerFrequency);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
m_sampleRate = sampleRate;
@ -818,9 +813,7 @@ bool SigMFFileInput::applySettings(const SigMFFileInputSettings& settings, const
{
qDebug() << "SigMFFileInput::applySettings: force: " << force << settings.getDebugString(settingsKeys, force);
if (settingsKeys.contains("accelerationFactor") || force)
{
if (m_fileInputWorker)
if (m_fileInputWorker && (settingsKeys.contains("accelerationFactor") || force))
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_sampleFifo.setSize(m_settings.m_accelerationFactor * m_sampleRate * sizeof(Sample))) {
@ -830,7 +823,6 @@ bool SigMFFileInput::applySettings(const SigMFFileInputSettings& settings, const
m_fileInputWorker->setAccelerationFactor(settings.m_accelerationFactor); // Fast Forward: 1 corresponds to live. 1/2 is half speed, 2 is double speed
}
}
if (settingsKeys.contains("fileName")) {
openFileStreams(settings.m_fileName);
@ -912,10 +904,10 @@ void SigMFFileInput::webapiUpdateDeviceSettings(
settings.m_reverseAPIAddress = *response.getSigMfFileInputSettings()->getReverseApiAddress();
}
if (deviceSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getSigMfFileInputSettings()->getReverseApiPort();
settings.m_reverseAPIPort = (uint16_t) response.getSigMfFileInputSettings()->getReverseApiPort();
}
if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getSigMfFileInputSettings()->getReverseApiDeviceIndex();
settings.m_reverseAPIDeviceIndex = (uint16_t) response.getSigMfFileInputSettings()->getReverseApiDeviceIndex();
}
}
@ -1067,7 +1059,11 @@ void SigMFFileInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& resp
response.getSigMfFileInputReport()->setSampleFormat(m_metaInfo.m_dataType.m_floatingPoint ? 1 : 0);
response.getSigMfFileInputReport()->setSampleSigned(m_metaInfo.m_dataType.m_signed ? 1 : 0);
response.getSigMfFileInputReport()->setSampleSwapIq(m_metaInfo.m_dataType.m_swapIQ ? 1 : 0);
response.getSigMfFileInputReport()->setCrcStatus(!m_crcAvailable ? 0 : m_crcOK ? 1 : 2);
if (!m_crcAvailable) {
response.getSigMfFileInputReport()->setCrcStatus(0);
} else {
response.getSigMfFileInputReport()->setCrcStatus(m_crcOK ? 1 : 2);
}
response.getSigMfFileInputReport()->setTotalBytesStatus(m_recordLengthOK);
response.getSigMfFileInputReport()->setTrackNumber(m_currentTrackIndex);
QList<SigMFFileCapture>::const_iterator it = m_captures.begin();
@ -1111,7 +1107,7 @@ void SigMFFileInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& resp
posRatio = (float) totalSamplesCount / (float) m_metaInfo.m_totalSamples;
response.getSigMfFileInputReport()->setRecordSamplesRatio(posRatio);
if (m_captures.size() > 0 )
if (!m_captures.empty() )
{
uint64_t totalTimeMs = m_captures.back().m_cumulativeTime + ((m_captures.back().m_length * 1000) / m_captures.back().m_sampleRate);
response.getSigMfFileInputReport()->setRecordDurationMs(totalTimeMs);
@ -1124,7 +1120,7 @@ void SigMFFileInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& resp
void SigMFFileInput::webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const SigMFFileInputSettings& settings, bool force)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
auto *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(0); // single Rx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("SigMFFileInput"));
@ -1153,8 +1149,8 @@ void SigMFFileInput::webapiReverseSendSettings(const QList<QString>& deviceSetti
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
@ -1167,7 +1163,7 @@ void SigMFFileInput::webapiReverseSendSettings(const QList<QString>& deviceSetti
void SigMFFileInput::webapiReverseSendStartStop(bool start)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
auto *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(0); // single Rx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("SigMFFileInput"));
@ -1179,8 +1175,8 @@ void SigMFFileInput::webapiReverseSendStartStop(bool start)
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
auto *buffer = new QBuffer();
buffer->open(QBuffer::ReadWrite);
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
QNetworkReply *reply;
@ -1195,7 +1191,7 @@ void SigMFFileInput::webapiReverseSendStartStop(bool start)
delete swgDeviceSettings;
}
void SigMFFileInput::networkManagerFinished(QNetworkReply *reply)
void SigMFFileInput::networkManagerFinished(QNetworkReply *reply) const
{
QNetworkReply::NetworkError replyError = reply->error();

View File

@ -86,7 +86,7 @@ public:
private:
bool m_working;
MsgConfigureTrackWork(bool working) :
explicit MsgConfigureTrackWork(bool working) :
Message(),
m_working(working)
{ }
@ -109,7 +109,7 @@ public:
private:
bool m_working;
MsgConfigureFileWork(bool working) :
explicit MsgConfigureFileWork(bool working) :
Message(),
m_working(working)
{ }
@ -132,7 +132,7 @@ public:
private:
int m_trackIndex;
MsgConfigureTrackIndex(int trackIndex) :
explicit MsgConfigureTrackIndex(int trackIndex) :
Message(),
m_trackIndex(trackIndex)
{ }
@ -152,10 +152,10 @@ public:
return new MsgConfigureTrackSeek(seekMillis);
}
protected:
private:
int m_seekMillis; //!< millis of seek position from the beginning 0..1000
MsgConfigureTrackSeek(int seekMillis) :
explicit MsgConfigureTrackSeek(int seekMillis) :
Message(),
m_seekMillis(seekMillis)
{ }
@ -175,10 +175,10 @@ public:
return new MsgConfigureFileSeek(seekMillis);
}
protected:
private:
int m_seekMillis; //!< millis of seek position from the beginning 0..1000
MsgConfigureFileSeek(int seekMillis) :
explicit MsgConfigureFileSeek(int seekMillis) :
Message(),
m_seekMillis(seekMillis)
{ }
@ -217,10 +217,10 @@ public:
return new MsgStartStop(startStop);
}
protected:
private:
bool m_startStop;
MsgStartStop(bool startStop) :
explicit MsgStartStop(bool startStop) :
Message(),
m_startStop(startStop)
{ }
@ -240,10 +240,10 @@ public:
return new MsgReportStartStop(startStop);
}
protected:
private:
bool m_startStop;
MsgReportStartStop(bool startStop) :
explicit MsgReportStartStop(bool startStop) :
Message(),
m_startStop(startStop)
{ }
@ -257,13 +257,13 @@ public:
public:
const SigMFFileMetaInfo& getMetaInfo() const { return m_metaInfo; }
const QList<SigMFFileCapture>& getCaptures() { return m_captures; }
const QList<SigMFFileCapture>& getCaptures() const { return m_captures; }
static MsgReportMetaData* create(const SigMFFileMetaInfo& metaInfo, const QList<SigMFFileCapture>& captures) {
return new MsgReportMetaData(metaInfo, captures);
}
protected:
private:
SigMFFileMetaInfo m_metaInfo;
QList<SigMFFileCapture> m_captures;
@ -288,7 +288,7 @@ public:
private:
int m_trackIndex;
MsgReportTrackChange(int trackIndex) :
explicit MsgReportTrackChange(int trackIndex) :
Message(),
m_trackIndex(trackIndex)
{ }
@ -321,7 +321,7 @@ public:
);
}
protected:
private:
quint64 m_samplesCount;
quint64 m_trackSamplesCount;
quint64 m_trackTimeStart;
@ -354,10 +354,10 @@ public:
return new MsgReportCRC(ok);
}
protected:
private:
bool m_ok;
MsgReportCRC(bool ok) :
explicit MsgReportCRC(bool ok) :
Message(),
m_ok(ok)
{ }
@ -376,63 +376,63 @@ public:
return new MsgReportTotalSamplesCheck(ok);
}
protected:
private:
bool m_ok;
MsgReportTotalSamplesCheck(bool ok) :
explicit MsgReportTotalSamplesCheck(bool ok) :
Message(),
m_ok(ok)
{ }
};
SigMFFileInput(DeviceAPI *deviceAPI);
virtual ~SigMFFileInput();
virtual void destroy();
explicit SigMFFileInput(DeviceAPI *deviceAPI);
~SigMFFileInput() final;
void destroy() final;
virtual void init();
virtual bool start();
virtual void stop();
void init() final;
bool start() final;
void stop() final;
virtual QByteArray serialize() const;
virtual bool deserialize(const QByteArray& data);
QByteArray serialize() const final;
bool deserialize(const QByteArray& data) final;
virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; }
virtual const QString& getDeviceDescription() const;
virtual int getSampleRate() const;
virtual void setSampleRate(int sampleRate) { (void) sampleRate; }
virtual quint64 getCenterFrequency() const;
virtual void setCenterFrequency(qint64 centerFrequency);
void setMessageQueueToGUI(MessageQueue *queue) final { m_guiMessageQueue = queue; }
const QString& getDeviceDescription() const final;
int getSampleRate() const final;
void setSampleRate(int sampleRate) final { (void) sampleRate; }
quint64 getCenterFrequency() const final;
void setCenterFrequency(qint64 centerFrequency) final;
quint64 getStartingTimeStamp() const;
virtual bool handleMessage(const Message& message);
bool handleMessage(const Message& message) final;
virtual int webapiSettingsGet(
int webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiSettingsPutPatch(
int webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiRunGet(
int webapiRunGet(
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiActionsPost(
int webapiActionsPost(
const QStringList& deviceActionsKeys,
SWGSDRangel::SWGDeviceActions& query,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiRun(
int webapiRun(
bool run,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
QString& errorMessage) final;
virtual int webapiReportGet(
int webapiReportGet(
SWGSDRangel::SWGDeviceReport& response,
QString& errorMessage);
QString& errorMessage) final;
static void webapiFormatDeviceSettings(
SWGSDRangel::SWGDeviceSettings& response,
@ -446,27 +446,28 @@ public:
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
bool m_running = false;
SigMFFileInputSettings m_settings;
std::ifstream m_metaStream;
std::ifstream m_dataStream;
SigMFFileMetaInfo m_metaInfo;
QList<SigMFFileCapture> m_captures;
std::vector<uint64_t> m_captureStarts;
bool m_trackMode;
int m_currentTrackIndex;
bool m_recordOpen;
bool m_crcAvailable;
bool m_crcOK;
bool m_recordLengthOK;
bool m_trackMode = false;
int m_currentTrackIndex = 0;
bool m_recordOpen = false;
bool m_crcAvailable = false;
bool m_crcOK = false;
bool m_recordLengthOK = false;
QString m_recordSummary;
SigMFFileInputWorker* m_fileInputWorker;
SigMFFileInputWorker* m_fileInputWorker = nullptr;
QThread m_fileInputWorkerThread;
QString m_deviceDescription;
int m_sampleRate;
unsigned int m_sampleBytes;
quint64 m_centerFrequency;
quint64 m_recordLength; //!< record length in seconds computed from file size
quint64 m_startingTimeStamp;
int m_sampleRate = 48000;
unsigned int m_sampleBytes = 1;
quint64 m_centerFrequency = 0;
quint64 m_recordLength = 0; //!< record length in seconds computed from file size
quint64 m_startingTimeStamp = 0;
QTimer m_masterTimer;
QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
@ -497,7 +498,7 @@ private:
void webapiReverseSendStartStop(bool start);
private slots:
void networkManagerFinished(QNetworkReply *reply);
void networkManagerFinished(QNetworkReply *reply) const;
};
#endif // INCLUDE_SIGMFFILEINPUT_H

View File

@ -481,6 +481,11 @@ bool SoapySDRInput::start()
//
// Note: this is quite similar to the BladeRF2 start handling. The main difference is that the channel allocation (enabling) process is
// done in the thread object.
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_openSuccess)
{
@ -595,11 +600,13 @@ void SoapySDRInput::stop()
//
// Note: this is quite similar to the BladeRF2 stop handling. The main difference is that the channel allocation (enabling) process is
// done in the thread object.
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
int requestedChannel = m_deviceAPI->getDeviceItemIndex();
SoapySDRInputThread *soapySDRInputThread = findThread();
@ -688,8 +695,6 @@ void SoapySDRInput::stop()
qDebug("SoapySDRInput::stop: MI mode. Not changing MI configuration. Just remove FIFO reference");
soapySDRInputThread->setFifo(requestedChannel, nullptr); // remove FIFO
}
m_running = false;
}
QByteArray SoapySDRInput::serialize() const

View File

@ -119,6 +119,11 @@ bool TestSourceInput::start()
void TestSourceInput::stop()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
if (m_testSourceWorkerThread)

View File

@ -414,14 +414,17 @@ void USRPInput::init()
bool USRPInput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_deviceShared.m_deviceParams->getDevice()) {
return false;
}
if (m_running) { stop(); }
if (!acquireChannel())
{
if (!acquireChannel()) {
return false;
}
@ -441,7 +444,14 @@ bool USRPInput::start()
void USRPInput::stop()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
qDebug("USRPInput::stop");
m_running = false;
if (m_usrpInputThread)
{
@ -451,7 +461,6 @@ void USRPInput::stop()
}
m_deviceShared.m_thread = 0;
m_running = false;
releaseChannel();
}

View File

@ -275,6 +275,11 @@ bool XTRXInput::start()
//
// Eventually it registers the FIFO in the thread. If the thread has to be started it enables the channels up to the number of channels
// allocated in the thread and starts the thread.
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
if (!m_deviceShared.m_dev || !m_deviceShared.m_dev->getDevice())
{
@ -353,8 +358,6 @@ bool XTRXInput::start()
xtrxInputThread->setFifo(requestedChannel, &m_sampleFifo);
xtrxInputThread->setLog2Decimation(requestedChannel, m_settings.m_log2SoftDecim);
applySettings(m_settings, QList<QString>(), true);
if (needsStart)
{
qDebug("XTRXInput::start: (re)start thread");
@ -364,6 +367,9 @@ bool XTRXInput::start()
qDebug("XTRXInput::start: started");
m_running = true;
m_mutex.unlock();
applySettings(m_settings, QList<QString>(), true);
return true;
}
@ -377,11 +383,13 @@ void XTRXInput::stop()
// If the thread is currently managing both channels (MI mode) then we are removing one channel. Thus we must
// transition from MI to SI. This transition is handled by stopping the thread, deleting it and creating a new one
// managing a single channel.
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
int removedChannel = m_deviceAPI->getDeviceItemIndex(); // channel to remove
int requestedChannel = removedChannel ^ 1; // channel to keep (opposite channel)
XTRXInputThread *xtrxInputThread = findThread();
@ -432,8 +440,6 @@ void XTRXInput::stop()
applySettings(m_settings, QList<QString>(), true);
xtrxInputThread->startWork();
}
m_running = false;
}
void XTRXInput::suspendTxThread()

View File

@ -65,9 +65,7 @@ DeviceAPI::DeviceAPI(
}
}
DeviceAPI::~DeviceAPI()
{
}
DeviceAPI::~DeviceAPI() = default;
void DeviceAPI::setSpectrumSinkInput(bool sourceElseSink, unsigned int index)
{
@ -269,7 +267,7 @@ DeviceAPI::EngineState DeviceAPI::state(int subsystemIndex) const
}
}
QString DeviceAPI::errorMessage(int subsystemIndex)
QString DeviceAPI::errorMessage(int subsystemIndex) const
{
if (m_deviceSourceEngine) {
return m_deviceSourceEngine->errorMessage();
@ -363,25 +361,25 @@ void DeviceAPI::setSamplingDevicePluginInterface(PluginInterface *iface)
m_pluginInterface = iface;
}
void DeviceAPI::getDeviceEngineStateStr(QString& state, int subsystemIndex)
void DeviceAPI::getDeviceEngineStateStr(QString& state, int subsystemIndex) const
{
if (m_deviceSourceEngine)
{
switch(m_deviceSourceEngine->state())
{
case DSPDeviceSourceEngine::StNotStarted:
case DSPDeviceSourceEngine::State::StNotStarted:
state = "notStarted";
break;
case DSPDeviceSourceEngine::StIdle:
case DSPDeviceSourceEngine::State::StIdle:
state = "idle";
break;
case DSPDeviceSourceEngine::StReady:
case DSPDeviceSourceEngine::State::StReady:
state = "ready";
break;
case DSPDeviceSourceEngine::StRunning:
case DSPDeviceSourceEngine::State::StRunning:
state = "running";
break;
case DSPDeviceSourceEngine::StError:
case DSPDeviceSourceEngine::State::StError:
state = "error";
break;
default:
@ -393,19 +391,19 @@ void DeviceAPI::getDeviceEngineStateStr(QString& state, int subsystemIndex)
{
switch(m_deviceSinkEngine->state())
{
case DSPDeviceSinkEngine::StNotStarted:
case DSPDeviceSinkEngine::State::StNotStarted:
state = "notStarted";
break;
case DSPDeviceSinkEngine::StIdle:
case DSPDeviceSinkEngine::State::StIdle:
state = "idle";
break;
case DSPDeviceSinkEngine::StReady:
case DSPDeviceSinkEngine::State::StReady:
state = "ready";
break;
case DSPDeviceSinkEngine::StRunning:
case DSPDeviceSinkEngine::State::StRunning:
state = "running";
break;
case DSPDeviceSinkEngine::StError:
case DSPDeviceSinkEngine::State::StError:
state = "error";
break;
default:
@ -417,19 +415,19 @@ void DeviceAPI::getDeviceEngineStateStr(QString& state, int subsystemIndex)
{
switch(m_deviceMIMOEngine->state(subsystemIndex))
{
case DSPDeviceMIMOEngine::StNotStarted:
case DSPDeviceMIMOEngine::State::StNotStarted:
state = "notStarted";
break;
case DSPDeviceMIMOEngine::StIdle:
case DSPDeviceMIMOEngine::State::StIdle:
state = "idle";
break;
case DSPDeviceMIMOEngine::StReady:
case DSPDeviceMIMOEngine::State::StReady:
state = "ready";
break;
case DSPDeviceMIMOEngine::StRunning:
case DSPDeviceMIMOEngine::State::StRunning:
state = "running";
break;
case DSPDeviceMIMOEngine::StError:
case DSPDeviceMIMOEngine::State::StError:
state = "error";
break;
default:
@ -546,26 +544,26 @@ bool DeviceAPI::deserialize(const QByteArray& data)
if (d.getVersion() == 1)
{
QByteArray data;
QByteArray bdata;
QList<quint64> centerFrequency;
if (m_deviceSourceEngine && m_deviceSourceEngine->getSource())
{
d.readBlob(1, &data);
d.readBlob(1, &bdata);
if (data.size() > 0) {
m_deviceSourceEngine->getSource()->deserialize(data);
}
}
if (m_deviceSinkEngine && m_deviceSinkEngine->getSink())
{
d.readBlob(2, &data);
d.readBlob(2, &bdata);
if (data.size() > 0) {
m_deviceSinkEngine->getSink()->deserialize(data);
}
}
if (m_deviceMIMOEngine && m_deviceMIMOEngine->getMIMO())
{
d.readBlob(3, &data);
d.readBlob(3, &bdata);
if (data.size() > 0) {
m_deviceMIMOEngine->getMIMO()->deserialize(data);
}
@ -596,7 +594,7 @@ void DeviceAPI::loadSamplingDeviceSettings(const Preset* preset)
qDebug("DeviceAPI::loadSamplingDeviceSettings: deserializing source %s[%d]: %s",
qPrintable(m_samplingDeviceId), m_samplingDeviceSequence, qPrintable(m_samplingDeviceSerial));
if (m_deviceSourceEngine->getSource() != 0) // Server flavor
if (m_deviceSourceEngine->getSource() != nullptr) // Server flavor
{
m_deviceSourceEngine->getSource()->deserialize(*sourceConfig);
}
@ -791,8 +789,8 @@ void DeviceAPI::removeBuddy(DeviceAPI* buddy)
void DeviceAPI::clearBuddiesLists()
{
std::vector<DeviceAPI*>::iterator itSource = m_sourceBuddies.begin();
std::vector<DeviceAPI*>::iterator itSink = m_sinkBuddies.begin();
auto itSource = m_sourceBuddies.begin();
auto itSink = m_sinkBuddies.begin();
bool leaderElected = false;
for (;itSource != m_sourceBuddies.end(); ++itSource)

View File

@ -65,7 +65,7 @@ public:
DSPDeviceSinkEngine *deviceSinkEngine,
DSPDeviceMIMOEngine *deviceMIMOEngine
);
~DeviceAPI();
~DeviceAPI() override;
void setSpectrumSinkInput(bool sourceElseSink = true, unsigned int index = 0); //!< Used in the MIMO case to select which stream is used as input to main spectrum
@ -94,7 +94,7 @@ public:
bool startDeviceEngine(int subsystemIndex = 0); //!< Start the device engine corresponding to the stream type
void stopDeviceEngine(int subsystemIndex = 0); //!< Stop the device engine corresponding to the stream type
EngineState state(int subsystemIndex = 0) const; //!< Return the state of the device engine corresponding to the stream type
QString errorMessage(int subsystemIndex = 0); //!< Last error message from the device engine
QString errorMessage(int subsystemIndex = 0) const; //!< Last error message from the device engine
uint getDeviceUID() const; //!< Return the current device engine unique ID
MessageQueue *getDeviceEngineInputMessageQueue(); //!< Device engine message queue
@ -131,7 +131,7 @@ public:
void setDeviceSetIndex(int deviceSetIndex);
PluginInterface *getPluginInterface() { return m_pluginInterface; }
void getDeviceEngineStateStr(QString& state, int subsystemIndex = 0);
void getDeviceEngineStateStr(QString& state, int subsystemIndex = 0) const;
ChannelAPI *getChanelSinkAPIAt(int index);
ChannelAPI *getChanelSourceAPIAt(int index);
@ -142,11 +142,7 @@ public:
int getNbMIMOChannels() const { return m_mimoChannelAPIs.size(); }
void loadSamplingDeviceSettings(const Preset* preset);
// void loadSourceSettings(const Preset* preset);
// void loadSinkSettings(const Preset* preset);
void saveSamplingDeviceSettings(Preset* preset);
// void saveSourceSettings(Preset* preset);
// void saveSinkSettings(Preset* preset);
QByteArray serialize() const override;
bool deserialize(const QByteArray& data) override;
@ -176,7 +172,7 @@ public:
const QTimer& getMasterTimer() const { return m_masterTimer; } //!< This is the DSPEngine master timer
protected:
private:
// common
StreamType m_streamType;
@ -217,7 +213,6 @@ protected:
DSPDeviceMIMOEngine *m_deviceMIMOEngine;
QList<ChannelAPI*> m_mimoChannelAPIs;
private:
void renumerateChannels();
private slots:

View File

@ -59,7 +59,7 @@ void DeviceSet::freeChannels()
for(int i = 0; i < m_channelInstanceRegistrations.count(); i++)
{
qDebug("DeviceSet::freeChannels: destroying channel [%s]", qPrintable(m_channelInstanceRegistrations[i]->getURI()));
m_channelInstanceRegistrations[i]->destroy();
delete m_channelInstanceRegistrations[i];
}
MainCore::instance()->clearChannels(this);
@ -87,7 +87,7 @@ void DeviceSet::deleteChannel(int channelIndex)
{
if (channelIndex < m_channelInstanceRegistrations.count())
{
m_channelInstanceRegistrations[channelIndex]->destroy();
delete m_channelInstanceRegistrations[channelIndex];
m_channelInstanceRegistrations.removeAt(channelIndex);
MainCore::instance()->removeChannelInstanceAt(this, channelIndex);
renameChannelInstances();
@ -141,7 +141,7 @@ void DeviceSet::loadRxChannelSettings(const Preset *preset, PluginAPI *pluginAPI
PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getRxChannelRegistrations();
// copy currently open channels and clear list
ChannelInstanceRegistrations openChannels = m_channelInstanceRegistrations;
QList<ChannelAPI*> openChannels = m_channelInstanceRegistrations;
m_channelInstanceRegistrations.clear();
mainCore->clearChannels(this);
@ -241,7 +241,7 @@ void DeviceSet::loadTxChannelSettings(const Preset *preset, PluginAPI *pluginAPI
PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getTxChannelRegistrations();
// copy currently open channels and clear list
ChannelInstanceRegistrations openChannels = m_channelInstanceRegistrations;
QList<ChannelAPI*> openChannels = m_channelInstanceRegistrations;
m_channelInstanceRegistrations.clear();
mainCore->clearChannels(this);
@ -339,7 +339,7 @@ void DeviceSet::loadMIMOChannelSettings(const Preset *preset, PluginAPI *pluginA
PluginAPI::ChannelRegistrations *channelRegistrations = pluginAPI->getMIMOChannelRegistrations();
// copy currently open channels and clear list
ChannelInstanceRegistrations openChannels = m_channelInstanceRegistrations;
QList<ChannelAPI*> openChannels = m_channelInstanceRegistrations;
m_channelInstanceRegistrations.clear();
mainCore->clearChannels(this);

View File

@ -86,9 +86,7 @@ public:
int webapiSpectrumServerDelete(SWGSDRangel::SWGSuccessResponse& response, QString& errorMessage);
private:
typedef QList<ChannelAPI*> ChannelInstanceRegistrations;
ChannelInstanceRegistrations m_channelInstanceRegistrations;
QList<ChannelAPI*> m_channelInstanceRegistrations;
int m_deviceTabIndex;
void renameChannelInstances();

File diff suppressed because it is too large Load Diff

View File

@ -19,12 +19,11 @@
#ifndef SDRBASE_DSP_DSPDEVICEMIMOENGINE_H_
#define SDRBASE_DSP_DSPDEVICEMIMOENGINE_H_
#include <QThread>
#include <QObject>
#include "dsp/dsptypes.h"
#include "util/message.h"
#include "util/messagequeue.h"
#include "util/syncmessenger.h"
#include "util/movingaverage.h"
#include "util/incrementalvector.h"
#include "export.h"
@ -34,14 +33,14 @@ class BasebandSampleSink;
class BasebandSampleSource;
class MIMOChannel;
class SDRBASE_API DSPDeviceMIMOEngine : public QThread {
class SDRBASE_API DSPDeviceMIMOEngine : public QObject {
Q_OBJECT
public:
class SetSampleMIMO : public Message {
MESSAGE_CLASS_DECLARATION
public:
SetSampleMIMO(DeviceSampleMIMO* sampleMIMO) : Message(), m_sampleMIMO(sampleMIMO) { }
explicit SetSampleMIMO(DeviceSampleMIMO* sampleMIMO) : Message(), m_sampleMIMO(sampleMIMO) { }
DeviceSampleMIMO* getSampleMIMO() const { return m_sampleMIMO; }
private:
DeviceSampleMIMO* m_sampleMIMO;
@ -81,7 +80,7 @@ public:
class AddMIMOChannel : public Message {
MESSAGE_CLASS_DECLARATION
public:
AddMIMOChannel(MIMOChannel* channel) :
explicit AddMIMOChannel(MIMOChannel* channel) :
Message(),
m_channel(channel)
{ }
@ -93,7 +92,7 @@ public:
class RemoveMIMOChannel : public Message {
MESSAGE_CLASS_DECLARATION
public:
RemoveMIMOChannel(MIMOChannel* channel) :
explicit RemoveMIMOChannel(MIMOChannel* channel) :
Message(),
m_channel(channel)
{ }
@ -135,7 +134,7 @@ public:
class AddSpectrumSink : public Message {
MESSAGE_CLASS_DECLARATION
public:
AddSpectrumSink(BasebandSampleSink* sampleSink) : Message(), m_sampleSink(sampleSink) { }
explicit AddSpectrumSink(BasebandSampleSink* sampleSink) : Message(), m_sampleSink(sampleSink) { }
BasebandSampleSink* getSampleSink() const { return m_sampleSink; }
private:
BasebandSampleSink* m_sampleSink;
@ -144,7 +143,7 @@ public:
class RemoveSpectrumSink : public Message {
MESSAGE_CLASS_DECLARATION
public:
RemoveSpectrumSink(BasebandSampleSink* sampleSink) : Message(), m_sampleSink(sampleSink) { }
explicit RemoveSpectrumSink(BasebandSampleSink* sampleSink) : Message(), m_sampleSink(sampleSink) { }
BasebandSampleSink* getSampleSink() const { return m_sampleSink; }
private:
BasebandSampleSink* m_sampleSink;
@ -153,7 +152,7 @@ public:
class GetErrorMessage : public Message {
MESSAGE_CLASS_DECLARATION
public:
GetErrorMessage(unsigned int subsystemIndex) :
explicit GetErrorMessage(unsigned int subsystemIndex) :
m_subsystemIndex(subsystemIndex)
{}
void setErrorMessage(const QString& text) { m_errorMessage = text; }
@ -205,7 +204,7 @@ public:
int m_index;
};
enum State {
enum class State {
StNotStarted, //!< engine is before initialization
StIdle, //!< engine is idle
StReady, //!< engine is ready to run
@ -214,13 +213,10 @@ public:
};
DSPDeviceMIMOEngine(uint32_t uid, QObject* parent = nullptr);
~DSPDeviceMIMOEngine();
~DSPDeviceMIMOEngine() override;
MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
void start(); //!< This thread start
void stop(); //!< This thread stop
bool initProcess(int subsystemIndex); //!< Initialize process sequence
bool startProcess(int subsystemIndex); //!< Start process sequence
void stopProcess(int subsystemIndex); //!< Stop process sequence
@ -248,25 +244,25 @@ public:
} else if (subsystemIndex == 1) {
return m_stateTx;
} else {
return StNotStarted;
return State::StNotStarted;
}
}
QString errorMessage(int subsystemIndex); //!< Return the current error message
QString deviceDescription(); //!< Return the device description
QString errorMessage(int subsystemIndex) const; //!< Return the current error message
QString deviceDescription() const; //!< Return the device description
void configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection, int isource); //!< Configure source DSP corrections
private:
struct SourceCorrection
{
bool m_dcOffsetCorrection;
bool m_iqImbalanceCorrection;
double m_iOffset;
double m_qOffset;
int m_iRange;
int m_qRange;
int m_imbalance;
bool m_dcOffsetCorrection = false;
bool m_iqImbalanceCorrection = false;
double m_iOffset = 0;
double m_qOffset = 0;
int m_iRange = 1 << 16;
int m_qRange = 1 << 16;
int m_imbalance = 65536;
MovingAverageUtil<int32_t, int64_t, 1024> m_iBeta;
MovingAverageUtil<int32_t, int64_t, 1024> m_qBeta;
#if IMBALANCE_INT
@ -288,13 +284,6 @@ private:
#endif
SourceCorrection()
{
m_dcOffsetCorrection = false;
m_iqImbalanceCorrection = false;
m_iOffset = 0;
m_qOffset = 0;
m_iRange = 1 << 16;
m_qRange = 1 << 16;
m_imbalance = 65536;
m_iBeta.reset();
m_qBeta.reset();
m_avgAmp.reset();
@ -320,19 +309,18 @@ private:
int m_sampleMIMOSequence;
MessageQueue m_inputMessageQueue; //<! Input message queue. Post here.
SyncMessenger m_syncMessenger; //!< Used to process messages synchronously with the thread
typedef std::list<BasebandSampleSink*> BasebandSampleSinks;
using BasebandSampleSinks = std::list<BasebandSampleSink *>;
std::vector<BasebandSampleSinks> m_basebandSampleSinks; //!< ancillary sample sinks on main thread (per input stream)
std::map<int, bool> m_rxRealElseComplex; //!< map of real else complex indicators for device sources (by input stream)
typedef std::list<BasebandSampleSource*> BasebandSampleSources;
using BasebandSampleSources = std::list<BasebandSampleSource *>;
std::vector<BasebandSampleSources> m_basebandSampleSources; //!< channel sample sources (per output stream)
std::map<int, bool> m_txRealElseComplex; //!< map of real else complex indicators for device sinks (by input stream)
std::vector<IncrementalVector<Sample>> m_sourceSampleBuffers;
std::vector<IncrementalVector<Sample>> m_sourceZeroBuffers;
unsigned int m_sumIndex; //!< channel index when summing channels
typedef std::list<MIMOChannel*> MIMOChannels;
using MIMOChannels = std::list<MIMOChannel *>;
MIMOChannels m_mimoChannels; //!< MIMO channels
std::vector<SourceCorrection> m_sourcesCorrections;
@ -341,7 +329,6 @@ private:
bool m_spectrumInputSourceElseSink; //!< Source else sink stream to be used as spectrum sink input
unsigned int m_spectrumInputIndex; //!< Index of the stream to be used as spectrum sink input
void run();
void workSampleSinkFifos(); //!< transfer samples of all sink streams (sync mode)
void workSampleSinkFifo(unsigned int streamIndex); //!< transfer samples of one sink stream (async mode)
void workSamplesSink(const SampleVector::const_iterator& vbegin, const SampleVector::const_iterator& vend, unsigned int streamIndex);
@ -358,13 +345,13 @@ private:
void handleSetMIMO(DeviceSampleMIMO* mimo); //!< Manage MIMO device setting
void iqCorrections(SampleVector::iterator begin, SampleVector::iterator end, int isource, bool imbalanceCorrection);
bool handleMessage(const Message& cmd);
private slots:
void handleDataRxSync(); //!< Handle data when Rx samples have to be processed synchronously
void handleDataRxAsync(int streamIndex); //!< Handle data when Rx samples have to be processed asynchronously
void handleDataTxSync(); //!< Handle data when Tx samples have to be processed synchronously
void handleDataTxAsync(int streamIndex); //!< Handle data when Tx samples have to be processed asynchronously
void handleSynchronousMessages(); //!< Handle synchronous messages with the thread
void handleInputMessages(); //!< Handle input message queue
signals:

View File

@ -28,9 +28,9 @@
#include "dsp/dspcommands.h"
DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) :
QThread(parent),
QObject(parent),
m_uid(uid),
m_state(StNotStarted),
m_state(State::StNotStarted),
m_deviceSampleSink(nullptr),
m_sampleSinkSequence(0),
m_basebandSampleSources(),
@ -39,16 +39,13 @@ DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) :
m_centerFrequency(0),
m_realElseComplex(false)
{
setState(State::StIdle);
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
connect(&m_syncMessenger, SIGNAL(messageSent()), this, SLOT(handleSynchronousMessages()), Qt::QueuedConnection);
moveToThread(this);
}
DSPDeviceSinkEngine::~DSPDeviceSinkEngine()
{
stop();
wait();
qDebug("DSPDeviceSinkEngine::~DSPDeviceSinkEngine");
}
void DSPDeviceSinkEngine::setState(State state)
@ -60,58 +57,35 @@ void DSPDeviceSinkEngine::setState(State state)
}
}
void DSPDeviceSinkEngine::run()
{
qDebug() << "DSPDeviceSinkEngine::run";
setState(StIdle);
exec();
}
void DSPDeviceSinkEngine::start()
{
qDebug() << "DSPDeviceSinkEngine::start";
QThread::start();
}
void DSPDeviceSinkEngine::stop()
{
qDebug() << "DSPDeviceSinkEngine::stop";
gotoIdle();
setState(StNotStarted);
QThread::exit();
// DSPExit cmd;
// m_syncMessenger.sendWait(cmd);
}
bool DSPDeviceSinkEngine::initGeneration()
{
qDebug() << "DSPDeviceSinkEngine::initGeneration";
DSPGenerationInit cmd;
return m_syncMessenger.sendWait(cmd) == StReady;
auto *cmd = new DSPGenerationInit();
getInputMessageQueue()->push(cmd);
return true;
}
bool DSPDeviceSinkEngine::startGeneration()
{
qDebug() << "DSPDeviceSinkEngine::startGeneration";
DSPGenerationStart cmd;
return m_syncMessenger.sendWait(cmd) == StRunning;
auto *cmd = new DSPGenerationStart();
getInputMessageQueue()->push(cmd);
return true;
}
void DSPDeviceSinkEngine::stopGeneration()
{
qDebug() << "DSPDeviceSinkEngine::stopGeneration";
DSPGenerationStop cmd;
m_syncMessenger.storeMessage(cmd);
handleSynchronousMessages();
auto *cmd = new DSPGenerationStop();
getInputMessageQueue()->push(cmd);
}
void DSPDeviceSinkEngine::setSink(DeviceSampleSink* sink)
{
qDebug() << "DSPDeviceSinkEngine::setSink";
DSPSetSink cmd(sink);
m_syncMessenger.sendWait(cmd);
m_deviceSampleSink = sink;
auto *cmd = new DSPSetSink(sink);
getInputMessageQueue()->push(cmd);
}
void DSPDeviceSinkEngine::setSinkSequence(int sequence)
@ -123,45 +97,40 @@ void DSPDeviceSinkEngine::setSinkSequence(int sequence)
void DSPDeviceSinkEngine::addChannelSource(BasebandSampleSource* source)
{
qDebug() << "DSPDeviceSinkEngine::addChannelSource: " << source->getSourceName().toStdString().c_str();
DSPAddBasebandSampleSource cmd(source);
m_syncMessenger.sendWait(cmd);
auto *cmd = new DSPAddBasebandSampleSource(source);
getInputMessageQueue()->push(cmd);
}
void DSPDeviceSinkEngine::removeChannelSource(BasebandSampleSource* source)
{
qDebug() << "DSPDeviceSinkEngine::removeChannelSource: " << source->getSourceName().toStdString().c_str();
DSPRemoveBasebandSampleSource cmd(source);
m_syncMessenger.sendWait(cmd);
auto *cmd = new DSPRemoveBasebandSampleSource(source);
getInputMessageQueue()->push(cmd);
}
void DSPDeviceSinkEngine::addSpectrumSink(BasebandSampleSink* spectrumSink)
{
qDebug() << "DSPDeviceSinkEngine::addSpectrumSink: " << spectrumSink->getSinkName().toStdString().c_str();
DSPAddSpectrumSink cmd(spectrumSink);
m_syncMessenger.sendWait(cmd);
m_spectrumSink = spectrumSink;
}
void DSPDeviceSinkEngine::removeSpectrumSink(BasebandSampleSink* spectrumSink)
{
qDebug() << "DSPDeviceSinkEngine::removeSpectrumSink: " << spectrumSink->getSinkName().toStdString().c_str();
DSPRemoveSpectrumSink cmd(spectrumSink);
m_syncMessenger.sendWait(cmd);
auto *cmd = new DSPRemoveSpectrumSink(spectrumSink);
getInputMessageQueue()->push(cmd);
}
QString DSPDeviceSinkEngine::errorMessage()
QString DSPDeviceSinkEngine::errorMessage() const
{
qDebug() << "DSPDeviceSinkEngine::errorMessage";
DSPGetErrorMessage cmd;
m_syncMessenger.sendWait(cmd);
return cmd.getErrorMessage();
return m_errorMessage;
}
QString DSPDeviceSinkEngine::sinkDeviceDescription()
QString DSPDeviceSinkEngine::sinkDeviceDescription() const
{
qDebug() << "DSPDeviceSinkEngine::sinkDeviceDescription";
DSPGetSinkDeviceDescription cmd;
m_syncMessenger.sendWait(cmd);
return cmd.getDeviceDescription();
return m_deviceDescription;
}
void DSPDeviceSinkEngine::workSampleFifo()
@ -173,7 +142,10 @@ void DSPDeviceSinkEngine::workSampleFifo()
}
SampleVector& data = sourceFifo->getData();
unsigned int iPart1Begin, iPart1End, iPart2Begin, iPart2End;
unsigned int iPart1Begin;
unsigned int iPart1End;
unsigned int iPart2Begin;
unsigned int iPart2End;
unsigned int remainder = sourceFifo->remainder();
while ((remainder > 0) && (m_inputMessageQueue.size() == 0))
@ -214,7 +186,7 @@ void DSPDeviceSinkEngine::workSamples(SampleVector& data, unsigned int iBegin, u
else
{
m_sourceSampleBuffer.allocate(nbSamples);
SampleVector::iterator sBegin = m_sourceSampleBuffer.m_vector.begin();
auto sBegin = m_sourceSampleBuffer.m_vector.begin();
BasebandSampleSources::const_iterator srcIt = m_basebandSampleSources.begin();
BasebandSampleSource *source = *srcIt;
source->pull(begin, nbSamples);
@ -230,7 +202,7 @@ void DSPDeviceSinkEngine::workSamples(SampleVector& data, unsigned int iBegin, u
sBegin + nbSamples,
data.begin() + iBegin,
data.begin() + iBegin,
[this](Sample& a, const Sample& b) -> Sample {
[this](const Sample& a, const Sample& b) -> Sample {
FixReal den = m_sumIndex + 1; // at each stage scale sum by n/n+1 and input by 1/n+1
FixReal nom = m_sumIndex; // so that final sum is scaled by N (number of channels)
FixReal x = a.real()/den + nom*(b.real()/den);
@ -256,20 +228,20 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoIdle()
qDebug() << "DSPDeviceSinkEngine::gotoIdle";
switch(m_state) {
case StNotStarted:
return StNotStarted;
case State::StNotStarted:
return State::StNotStarted;
case StIdle:
case StError:
return StIdle;
case State::StIdle:
case State::StError:
return State::StIdle;
case StReady:
case StRunning:
case State::StReady:
case State::StRunning:
break;
}
if (!m_deviceSampleSink) {
return StIdle;
return State::StIdle;
}
// stop everything
@ -284,23 +256,23 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoIdle()
m_deviceDescription.clear();
m_sampleRate = 0;
return StIdle;
return State::StIdle;
}
DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoInit()
{
switch(m_state) {
case StNotStarted:
return StNotStarted;
case State::StNotStarted:
return State::StNotStarted;
case StRunning: // FIXME: assumes it goes first through idle state. Could we get back to init from running directly?
return StRunning;
case State::StRunning:
return State::StRunning;
case StReady:
return StReady;
case State::StReady:
return State::StReady;
case StIdle:
case StError:
case State::StIdle:
case State::StError:
break;
}
@ -334,11 +306,11 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoInit()
// pass data to listeners
if (m_deviceSampleSink->getMessageQueueToGUI())
{
DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy for the output queue
auto* rep = new DSPSignalNotification(notif); // make a copy for the output queue
m_deviceSampleSink->getMessageQueueToGUI()->push(rep);
}
return StReady;
return State::StReady;
}
DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoRunning()
@ -347,17 +319,17 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoRunning()
switch(m_state)
{
case StNotStarted:
return StNotStarted;
case State::StNotStarted:
return State::StNotStarted;
case StIdle:
return StIdle;
case State::StIdle:
return State::StIdle;
case StRunning:
return StRunning;
case State::StRunning:
return State::StRunning;
case StReady:
case StError:
case State::StReady:
case State::StError:
break;
}
@ -386,7 +358,7 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoRunning()
qDebug() << "DSPDeviceSinkEngine::gotoRunning: input message queue pending: " << m_inputMessageQueue.size();
return StRunning;
return State::StRunning;
}
DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoError(const QString& errorMessage)
@ -395,19 +367,17 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoError(const QString& errorMe
m_errorMessage = errorMessage;
m_deviceDescription.clear();
setState(StError);
return StError;
setState(State::StError);
return State::StError;
}
void DSPDeviceSinkEngine::handleSetSink(DeviceSampleSink* sink)
void DSPDeviceSinkEngine::handleSetSink(const DeviceSampleSink*)
{
m_deviceSampleSink = sink;
if (!m_deviceSampleSink) { // Early leave
return;
}
qDebug("DSPDeviceSinkEngine::handleSetSink: set %s", qPrintable(sink->getDeviceDescription()));
qDebug("DSPDeviceSinkEngine::handleSetSink: set %s", qPrintable(m_deviceSampleSink->getDeviceDescription()));
QObject::connect(
m_deviceSampleSink->getSampleFifo(),
@ -416,107 +386,26 @@ void DSPDeviceSinkEngine::handleSetSink(DeviceSampleSink* sink)
&DSPDeviceSinkEngine::handleData,
Qt::QueuedConnection
);
}
void DSPDeviceSinkEngine::handleData()
{
if (m_state == StRunning) {
if (m_state == State::StRunning) {
workSampleFifo();
}
}
void DSPDeviceSinkEngine::handleSynchronousMessages()
bool DSPDeviceSinkEngine::handleMessage(const Message& message)
{
Message *message = m_syncMessenger.getMessage();
qDebug() << "DSPDeviceSinkEngine::handleSynchronousMessages: " << message->getIdentifier();
if (DSPGenerationInit::match(*message))
if (DSPSignalNotification::match(message))
{
setState(gotoIdle());
if(m_state == StIdle) {
setState(gotoInit()); // State goes ready if init is performed
}
}
else if (DSPGenerationStart::match(*message))
{
if(m_state == StReady) {
setState(gotoRunning());
}
}
else if (DSPGenerationStop::match(*message))
{
setState(gotoIdle());
}
else if (DSPGetSinkDeviceDescription::match(*message))
{
((DSPGetSinkDeviceDescription*) message)->setDeviceDescription(m_deviceDescription);
}
else if (DSPGetErrorMessage::match(*message))
{
((DSPGetErrorMessage*) message)->setErrorMessage(m_errorMessage);
}
else if (DSPSetSink::match(*message)) {
handleSetSink(((DSPSetSink*) message)->getSampleSink());
}
else if (DSPAddSpectrumSink::match(*message))
{
m_spectrumSink = ((DSPAddSpectrumSink*) message)->getSampleSink();
}
else if (DSPRemoveSpectrumSink::match(*message))
{
BasebandSampleSink* spectrumSink = ((DSPRemoveSpectrumSink*) message)->getSampleSink();
if(m_state == StRunning) {
spectrumSink->stop();
}
m_spectrumSink = nullptr;
}
else if (DSPAddBasebandSampleSource::match(*message))
{
BasebandSampleSource* source = ((DSPAddBasebandSampleSource*) message)->getSampleSource();
m_basebandSampleSources.push_back(source);
DSPSignalNotification *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
source->pushMessage(notif);
if (m_state == StRunning)
{
source->start();
}
}
else if (DSPRemoveBasebandSampleSource::match(*message))
{
BasebandSampleSource* source = ((DSPRemoveBasebandSampleSource*) message)->getSampleSource();
if(m_state == StRunning) {
source->stop();
}
m_basebandSampleSources.remove(source);
}
m_syncMessenger.done(m_state);
}
void DSPDeviceSinkEngine::handleInputMessages()
{
Message* message;
while ((message = m_inputMessageQueue.pop()) != 0)
{
qDebug("DSPDeviceSinkEngine::handleInputMessages: message: %s", message->getIdentifier());
if (DSPSignalNotification::match(*message))
{
DSPSignalNotification *notif = (DSPSignalNotification *) message;
auto& notif = (const DSPSignalNotification&) message;
// update DSP values
m_sampleRate = notif->getSampleRate();
m_centerFrequency = notif->getCenterFrequency();
m_realElseComplex = notif->getRealElseComplex();
m_sampleRate = notif.getSampleRate();
m_centerFrequency = notif.getCenterFrequency();
m_realElseComplex = notif.getRealElseComplex();
qDebug() << "DSPDeviceSinkEngine::handleInputMessages: DSPSignalNotification:"
<< " m_sampleRate: " << m_sampleRate
@ -527,7 +416,7 @@ void DSPDeviceSinkEngine::handleInputMessages()
for(BasebandSampleSources::const_iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); it++)
{
DSPSignalNotification* rep = new DSPSignalNotification(*notif); // make a copy
auto *rep = new DSPSignalNotification(notif); // make a copy
qDebug() << "DSPDeviceSinkEngine::handleInputMessages: forward message to " << (*it)->getSourceName().toStdString().c_str();
(*it)->pushMessage(rep);
}
@ -540,11 +429,93 @@ void DSPDeviceSinkEngine::handleInputMessages()
if (guiMessageQueue)
{
DSPSignalNotification* rep = new DSPSignalNotification(*notif); // make a copy for the output queue
auto *rep = new DSPSignalNotification(notif); // make a copy for the output queue
guiMessageQueue->push(rep);
}
}
return true;
}
// From synchronous messages
if (DSPGenerationInit::match(message))
{
setState(gotoIdle());
if(m_state == State::StIdle) {
setState(gotoInit()); // State goes ready if init is performed
}
return true;
}
else if (DSPGenerationStart::match(message))
{
if(m_state == State::StReady) {
setState(gotoRunning());
}
return true;
}
else if (DSPGenerationStop::match(message))
{
setState(gotoIdle());
return true;
}
else if (DSPSetSink::match(message))
{
const auto& cmd = (const DSPSetSink&) message;
handleSetSink(cmd.getSampleSink());
return true;
}
else if (DSPRemoveSpectrumSink::match(message))
{
auto& cmd = (const DSPRemoveSpectrumSink&) message;
BasebandSampleSink* spectrumSink = cmd.getSampleSink();
if(m_state == State::StRunning) {
spectrumSink->stop();
}
m_spectrumSink = nullptr;
return true;
}
else if (DSPAddBasebandSampleSource::match(message))
{
auto& cmd = (const DSPAddBasebandSampleSource&) message;
BasebandSampleSource* source = cmd.getSampleSource();
m_basebandSampleSources.push_back(source);
auto *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
source->pushMessage(notif);
if (m_state == State::StRunning) {
source->start();
}
return true;
}
else if (DSPRemoveBasebandSampleSource::match(message))
{
auto& cmd = (const DSPRemoveBasebandSampleSource&) message;
BasebandSampleSource* source = cmd.getSampleSource();
if(m_state == State::StRunning) {
source->stop();
}
m_basebandSampleSources.remove(source);
return true;
}
return false;
}
void DSPDeviceSinkEngine::handleInputMessages()
{
Message* message;
while ((message = m_inputMessageQueue.pop()) != nullptr)
{
qDebug("DSPDeviceSinkEngine::handleInputMessages: message: %s", message->getIdentifier());
if (handleMessage(*message)) {
delete message;
}
}

View File

@ -22,7 +22,7 @@
#ifndef SDRBASE_DSP_DSPDEVICESINKENGINE_H_
#define SDRBASE_DSP_DSPDEVICESINKENGINE_H_
#include <QThread>
#include <QObject>
#include <QTimer>
#include <QMutex>
#include <QWaitCondition>
@ -33,7 +33,6 @@
#include "dsp/dsptypes.h"
#include "util/messagequeue.h"
#include "util/syncmessenger.h"
#include "util/incrementalvector.h"
#include "export.h"
@ -41,11 +40,11 @@ class DeviceSampleSink;
class BasebandSampleSource;
class BasebandSampleSink;
class SDRBASE_API DSPDeviceSinkEngine : public QThread {
class SDRBASE_API DSPDeviceSinkEngine : public QObject {
Q_OBJECT
public:
enum State {
enum class State {
StNotStarted, //!< engine is before initialization
StIdle, //!< engine is idle
StReady, //!< engine is ready to run
@ -53,16 +52,13 @@ public:
StError //!< engine is in error
};
DSPDeviceSinkEngine(uint32_t uid, QObject* parent = NULL);
~DSPDeviceSinkEngine();
DSPDeviceSinkEngine(uint32_t uid, QObject* parent = nullptr);
~DSPDeviceSinkEngine() final;
uint32_t getUID() const { return m_uid; }
MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
void start(); //!< This thread start
void stop(); //!< This thread stop
bool initGeneration(); //!< Initialize generation sequence
bool startGeneration(); //!< Start generation sequence
void stopGeneration(); //!< Stop generation sequence
@ -79,14 +75,13 @@ public:
State state() const { return m_state; } //!< Return DSP engine current state
QString errorMessage(); //!< Return the current error message
QString sinkDeviceDescription(); //!< Return the sink device description
QString errorMessage() const; //!< Return the current error message
QString sinkDeviceDescription() const; //!< Return the sink device description
private:
uint32_t m_uid; //!< unique ID
MessageQueue m_inputMessageQueue; //<! Input message queue. Post here.
SyncMessenger m_syncMessenger; //!< Used to process messages synchronously with the thread
State m_state;
@ -96,7 +91,7 @@ private:
DeviceSampleSink* m_deviceSampleSink;
int m_sampleSinkSequence;
typedef std::list<BasebandSampleSource*> BasebandSampleSources;
using BasebandSampleSources = std::list<BasebandSampleSource *>;
BasebandSampleSources m_basebandSampleSources; //!< baseband sample sources within main thread (usually file input)
BasebandSampleSink *m_spectrumSink;
@ -108,7 +103,6 @@ private:
bool m_realElseComplex;
unsigned int m_sumIndex; //!< channel index when summing channels
void run();
void workSampleFifo(); //!< transfer samples from baseband sources to sink if in running state
void workSamples(SampleVector& data, unsigned int iBegin, unsigned int iEnd);
@ -118,12 +112,12 @@ private:
State gotoError(const QString& errorMsg); //!< Go to an error state
void setState(State state);
void handleSetSink(DeviceSampleSink* sink); //!< Manage sink setting
void handleSetSink(const DeviceSampleSink* sink); //!< Manage sink setting
bool handleMessage(const Message& cmd);
private slots:
void handleData(); //!< Handle data when samples have to be written to the sample FIFO
void handleInputMessages(); //!< Handle input message queue
void handleSynchronousMessages(); //!< Handle synchronous messages with the thread
signals:
void stateChanged();

View File

@ -29,9 +29,9 @@
#include "samplesinkfifo.h"
DSPDeviceSourceEngine::DSPDeviceSourceEngine(uint uid, QObject* parent) :
QThread(parent),
QObject(parent),
m_uid(uid),
m_state(StNotStarted),
m_state(State::StNotStarted),
m_deviceSampleSource(nullptr),
m_sampleSourceSequence(0),
m_basebandSampleSinks(),
@ -46,16 +46,13 @@ DSPDeviceSourceEngine::DSPDeviceSourceEngine(uint uid, QObject* parent) :
m_qRange(1 << 16),
m_imbalance(65536)
{
setState(State::StIdle);
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
connect(&m_syncMessenger, SIGNAL(messageSent()), this, SLOT(handleSynchronousMessages()), Qt::QueuedConnection);
moveToThread(this);
}
DSPDeviceSourceEngine::~DSPDeviceSourceEngine()
{
stop();
wait();
qDebug("DSPDeviceSourceEngine::~DSPDeviceSourceEngine");
}
void DSPDeviceSourceEngine::setState(State state)
@ -67,63 +64,36 @@ void DSPDeviceSourceEngine::setState(State state)
}
}
void DSPDeviceSourceEngine::run()
bool DSPDeviceSourceEngine::initAcquisition() const
{
qDebug() << "DSPDeviceSourceEngine::run";
setState(StIdle);
exec();
}
void DSPDeviceSourceEngine::start()
{
qDebug() << "DSPDeviceSourceEngine::start";
QThread::start();
}
void DSPDeviceSourceEngine::stop()
{
qDebug() << "DSPDeviceSourceEngine::stop";
gotoIdle();
setState(StNotStarted);
QThread::exit();
// DSPExit cmd;
// m_syncMessenger.sendWait(cmd);
}
bool DSPDeviceSourceEngine::initAcquisition()
{
qDebug() << "DSPDeviceSourceEngine::initAcquisition";
DSPAcquisitionInit cmd;
return m_syncMessenger.sendWait(cmd) == StReady;
qDebug("DSPDeviceSourceEngine::initAcquisition (dummy)");
return true;
}
bool DSPDeviceSourceEngine::startAcquisition()
{
qDebug() << "DSPDeviceSourceEngine::startAcquisition";
DSPAcquisitionStart cmd;
return m_syncMessenger.sendWait(cmd) == StRunning;
qDebug("DSPDeviceSourceEngine::startAcquisition");
auto *cmd = new DSPAcquisitionStart();
getInputMessageQueue()->push(cmd);
return true;
}
void DSPDeviceSourceEngine::stopAcquistion()
{
qDebug() << "DSPDeviceSourceEngine::stopAcquistion";
DSPAcquisitionStop cmd;
m_syncMessenger.storeMessage(cmd);
handleSynchronousMessages();
qDebug("DSPDeviceSourceEngine::stopAcquistion");
auto *cmd = new DSPAcquisitionStop();
getInputMessageQueue()->push(cmd);
if(m_dcOffsetCorrection)
{
if (m_dcOffsetCorrection) {
qDebug("DC offset:%f,%f", m_iOffset, m_qOffset);
}
}
void DSPDeviceSourceEngine::setSource(DeviceSampleSource* source)
{
qDebug() << "DSPDeviceSourceEngine::setSource";
DSPSetSource cmd(source);
m_syncMessenger.sendWait(cmd);
qDebug("DSPDeviceSourceEngine::setSource");
auto *cmd = new DSPSetSource(source);
getInputMessageQueue()->push(cmd);
}
void DSPDeviceSourceEngine::setSourceSequence(int sequence)
@ -135,38 +105,34 @@ void DSPDeviceSourceEngine::setSourceSequence(int sequence)
void DSPDeviceSourceEngine::addSink(BasebandSampleSink* sink)
{
qDebug() << "DSPDeviceSourceEngine::addSink: " << sink->getSinkName().toStdString().c_str();
DSPAddBasebandSampleSink cmd(sink);
m_syncMessenger.sendWait(cmd);
auto *cmd = new DSPAddBasebandSampleSink(sink);
getInputMessageQueue()->push(cmd);
}
void DSPDeviceSourceEngine::removeSink(BasebandSampleSink* sink)
{
qDebug() << "DSPDeviceSourceEngine::removeSink: " << sink->getSinkName().toStdString().c_str();
DSPRemoveBasebandSampleSink cmd(sink);
m_syncMessenger.sendWait(cmd);
auto *cmd = new DSPRemoveBasebandSampleSink(sink);
getInputMessageQueue()->push(cmd);
}
void DSPDeviceSourceEngine::configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection)
{
qDebug() << "DSPDeviceSourceEngine::configureCorrections";
DSPConfigureCorrection* cmd = new DSPConfigureCorrection(dcOffsetCorrection, iqImbalanceCorrection);
m_inputMessageQueue.push(cmd);
qDebug("DSPDeviceSourceEngine::configureCorrections");
auto *cmd = new DSPConfigureCorrection(dcOffsetCorrection, iqImbalanceCorrection);
getInputMessageQueue()->push(cmd);
}
QString DSPDeviceSourceEngine::errorMessage()
QString DSPDeviceSourceEngine::errorMessage() const
{
qDebug() << "DSPDeviceSourceEngine::errorMessage";
DSPGetErrorMessage cmd;
m_syncMessenger.sendWait(cmd);
return cmd.getErrorMessage();
qDebug("DSPDeviceSourceEngine::errorMessage");
return m_errorMessage;
}
QString DSPDeviceSourceEngine::sourceDeviceDescription()
QString DSPDeviceSourceEngine::sourceDeviceDescription() const
{
qDebug() << "DSPDeviceSourceEngine::sourceDeviceDescription";
DSPGetSourceDeviceDescription cmd;
m_syncMessenger.sendWait(cmd);
return cmd.getDeviceDescription();
qDebug("DSPDeviceSourceEngine::sourceDeviceDescription");
return m_deviceDescription;
}
void DSPDeviceSourceEngine::iqCorrections(SampleVector::iterator begin, SampleVector::iterator end, bool imbalanceCorrection)
@ -217,8 +183,8 @@ void DSPDeviceSourceEngine::iqCorrections(SampleVector::iterator begin, SampleVe
#else
// DC correction and conversion
float xi = (it->m_real - (int32_t) m_iBeta) / SDR_RX_SCALEF;
float xq = (it->m_imag - (int32_t) m_qBeta) / SDR_RX_SCALEF;
float xi = (float) (it->m_real - (int32_t) m_iBeta) / SDR_RX_SCALEF;
float xq = (float) (it->m_imag - (int32_t) m_qBeta) / SDR_RX_SCALEF;
// phase imbalance
m_avgII(xi*xi); // <I", I">
@ -229,8 +195,8 @@ void DSPDeviceSourceEngine::iqCorrections(SampleVector::iterator begin, SampleVe
m_avgPhi(m_avgIQ.asDouble()/m_avgII.asDouble());
}
float& yi = xi; // the in phase remains the reference
float yq = xq - m_avgPhi.asDouble()*xi;
const float& yi = xi; // the in phase remains the reference
float yq = xq - (float) m_avgPhi.asDouble()*xi;
// amplitude I/Q imbalance
m_avgII2(yi*yi); // <I, I>
@ -241,12 +207,12 @@ void DSPDeviceSourceEngine::iqCorrections(SampleVector::iterator begin, SampleVe
}
// final correction
float& zi = yi; // the in phase remains the reference
float zq = m_avgAmp.asDouble() * yq;
const float& zi = yi; // the in phase remains the reference
auto zq = (float) (m_avgAmp.asDouble() * yq);
// convert and store
it->m_real = zi * SDR_RX_SCALEF;
it->m_imag = zq * SDR_RX_SCALEF;
it->m_real = (FixReal) (zi * SDR_RX_SCALEF);
it->m_imag = (FixReal) (zq * SDR_RX_SCALEF);
#endif
}
else
@ -376,23 +342,23 @@ void DSPDeviceSourceEngine::work()
DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoIdle()
{
qDebug() << "DSPDeviceSourceEngine::gotoIdle";
qDebug("DSPDeviceSourceEngine::gotoIdle");
switch(m_state) {
case StNotStarted:
return StNotStarted;
case State::StNotStarted:
return State::StNotStarted;
case StIdle:
case StError:
return StIdle;
case State::StIdle:
case State::StError:
return State::StIdle;
case StReady:
case StRunning:
case State::StReady:
case State::StRunning:
break;
}
if (!m_deviceSampleSource) {
return StIdle;
return State::StIdle;
}
// stop everything
@ -406,23 +372,23 @@ DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoIdle()
m_deviceDescription.clear();
m_sampleRate = 0;
return StIdle;
return State::StIdle;
}
DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoInit()
{
switch(m_state) {
case StNotStarted:
return StNotStarted;
case State::StNotStarted:
return State::StNotStarted;
case StRunning: // FIXME: assumes it goes first through idle state. Could we get back to init from running directly?
return StRunning;
case State::StRunning:
return State::StRunning;
case StReady:
return StReady;
case State::StReady:
return State::StReady;
case StIdle:
case StError:
case State::StIdle:
case State::StError:
break;
}
@ -449,7 +415,7 @@ DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoInit()
for (BasebandSampleSinks::const_iterator it = m_basebandSampleSinks.begin(); it != m_basebandSampleSinks.end(); ++it)
{
DSPSignalNotification *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
auto *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
qDebug() << "DSPDeviceSourceEngine::gotoInit: initializing " << (*it)->getSinkName().toStdString().c_str();
(*it)->pushMessage(notif);
}
@ -457,30 +423,30 @@ DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoInit()
// pass data to listeners
if (m_deviceSampleSource->getMessageQueueToGUI())
{
DSPSignalNotification* rep = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
auto *rep = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
m_deviceSampleSource->getMessageQueueToGUI()->push(rep);
}
return StReady;
return State::StReady;
}
DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoRunning()
{
qDebug() << "DSPDeviceSourceEngine::gotoRunning";
qDebug("DSPDeviceSourceEngine::gotoRunning");
switch(m_state)
{
case StNotStarted:
return StNotStarted;
case State::StNotStarted:
return State::StNotStarted;
case StIdle:
return StIdle;
case State::StIdle:
return State::StIdle;
case StRunning:
return StRunning;
case State::StRunning:
return State::StRunning;
case StReady:
case StError:
case State::StReady:
case State::StError:
break;
}
@ -504,7 +470,7 @@ DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoRunning()
qDebug() << "DSPDeviceSourceEngine::gotoRunning:input message queue pending: " << m_inputMessageQueue.size();
return StRunning;
return State::StRunning;
}
DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoError(const QString& errorMessage)
@ -513,19 +479,14 @@ DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoError(const QString& err
m_errorMessage = errorMessage;
m_deviceDescription.clear();
setState(StError);
return StError;
setState(State::StError);
return State::StError;
}
void DSPDeviceSourceEngine::handleSetSource(DeviceSampleSource* source)
{
gotoIdle();
// if(m_sampleSource != 0)
// {
// disconnect(m_sampleSource->getSampleFifo(), SIGNAL(dataReady()), this, SLOT(handleData()));
// }
m_deviceSampleSource = source;
if (m_deviceSampleSource)
@ -541,95 +502,29 @@ void DSPDeviceSourceEngine::handleSetSource(DeviceSampleSource* source)
void DSPDeviceSourceEngine::handleData()
{
if(m_state == StRunning)
if(m_state == State::StRunning)
{
work();
}
}
void DSPDeviceSourceEngine::handleSynchronousMessages()
bool DSPDeviceSourceEngine::handleMessage(const Message& message)
{
Message *message = m_syncMessenger.getMessage();
qDebug() << "DSPDeviceSourceEngine::handleSynchronousMessages: " << message->getIdentifier();
if (DSPConfigureCorrection::match(message))
{
auto& conf = (const DSPConfigureCorrection&) message;
m_iqImbalanceCorrection = conf.getIQImbalanceCorrection();
if (DSPAcquisitionInit::match(*message))
if (m_dcOffsetCorrection != conf.getDCOffsetCorrection())
{
setState(gotoIdle());
if(m_state == StIdle) {
setState(gotoInit()); // State goes ready if init is performed
}
}
else if (DSPAcquisitionStart::match(*message))
{
if(m_state == StReady) {
setState(gotoRunning());
}
}
else if (DSPAcquisitionStop::match(*message))
{
setState(gotoIdle());
}
else if (DSPGetSourceDeviceDescription::match(*message))
{
((DSPGetSourceDeviceDescription*) message)->setDeviceDescription(m_deviceDescription);
}
else if (DSPGetErrorMessage::match(*message))
{
((DSPGetErrorMessage*) message)->setErrorMessage(m_errorMessage);
}
else if (DSPSetSource::match(*message)) {
handleSetSource(((DSPSetSource*) message)->getSampleSource());
}
else if (DSPAddBasebandSampleSink::match(*message))
{
BasebandSampleSink* sink = ((DSPAddBasebandSampleSink*) message)->getSampleSink();
m_basebandSampleSinks.push_back(sink);
// initialize sample rate and center frequency in the sink:
DSPSignalNotification *msg = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
sink->pushMessage(msg);
// start the sink:
if(m_state == StRunning) {
sink->start();
}
}
else if (DSPRemoveBasebandSampleSink::match(*message))
{
BasebandSampleSink* sink = ((DSPRemoveBasebandSampleSink*) message)->getSampleSink();
if(m_state == StRunning) {
sink->stop();
}
m_basebandSampleSinks.remove(sink);
}
m_syncMessenger.done(m_state);
}
void DSPDeviceSourceEngine::handleInputMessages()
{
Message* message;
while ((message = m_inputMessageQueue.pop()) != 0)
{
qDebug("DSPDeviceSourceEngine::handleInputMessages: message: %s", message->getIdentifier());
if (DSPConfigureCorrection::match(*message))
{
DSPConfigureCorrection* conf = (DSPConfigureCorrection*) message;
m_iqImbalanceCorrection = conf->getIQImbalanceCorrection();
if(m_dcOffsetCorrection != conf->getDCOffsetCorrection())
{
m_dcOffsetCorrection = conf->getDCOffsetCorrection();
m_dcOffsetCorrection = conf.getDCOffsetCorrection();
m_iOffset = 0;
m_qOffset = 0;
}
if(m_iqImbalanceCorrection != conf->getIQImbalanceCorrection())
if (m_iqImbalanceCorrection != conf.getIQImbalanceCorrection())
{
m_iqImbalanceCorrection = conf->getIQImbalanceCorrection();
m_iqImbalanceCorrection = conf.getIQImbalanceCorrection();
m_iRange = 1 << 16;
m_qRange = 1 << 16;
m_imbalance = 65536;
@ -644,17 +539,17 @@ void DSPDeviceSourceEngine::handleInputMessages()
m_iBeta.reset();
m_qBeta.reset();
delete message;
return true;
}
else if (DSPSignalNotification::match(*message))
else if (DSPSignalNotification::match(message))
{
DSPSignalNotification *notif = (DSPSignalNotification *) message;
auto& notif = (const DSPSignalNotification&) message;
// update DSP values
m_sampleRate = notif->getSampleRate();
m_centerFrequency = notif->getCenterFrequency();
m_realElseComplex = notif->getRealElseComplex();
m_sampleRate = notif.getSampleRate();
m_centerFrequency = notif.getCenterFrequency();
m_realElseComplex = notif.getRealElseComplex();
qDebug() << "DSPDeviceSourceEngine::handleInputMessages: DSPSignalNotification:"
<< " m_sampleRate: " << m_sampleRate
@ -664,7 +559,7 @@ void DSPDeviceSourceEngine::handleInputMessages()
for(BasebandSampleSinks::const_iterator it = m_basebandSampleSinks.begin(); it != m_basebandSampleSinks.end(); it++)
{
DSPSignalNotification* rep = new DSPSignalNotification(*notif); // make a copy
auto* rep = new DSPSignalNotification(notif); // make a copy
qDebug() << "DSPDeviceSourceEngine::handleInputMessages: forward message to " << (*it)->getSinkName().toStdString().c_str();
(*it)->pushMessage(rep);
}
@ -677,11 +572,79 @@ void DSPDeviceSourceEngine::handleInputMessages()
if (guiMessageQueue)
{
DSPSignalNotification* rep = new DSPSignalNotification(*notif); // make a copy for the source GUI
auto* rep = new DSPSignalNotification(notif); // make a copy for the source GUI
guiMessageQueue->push(rep);
}
}
return true;
}
// was in handleSynchronousMessages:
else if (DSPAcquisitionInit::match(message))
{
return true; // discard
}
else if (DSPAcquisitionStart::match(message))
{
setState(gotoIdle());
if(m_state == State::StIdle) {
setState(gotoInit()); // State goes ready if init is performed
}
if(m_state == State::StReady) {
setState(gotoRunning());
}
return true;
}
else if (DSPAcquisitionStop::match(message))
{
setState(gotoIdle());
return true;
}
else if (DSPSetSource::match(message))
{
auto cmd = (const DSPSetSource&) message;
handleSetSource(cmd.getSampleSource());
}
else if (DSPAddBasebandSampleSink::match(message))
{
auto cmd = (const DSPAddBasebandSampleSink&) message;
BasebandSampleSink* sink = cmd.getSampleSink();
m_basebandSampleSinks.push_back(sink);
// initialize sample rate and center frequency in the sink:
auto *msg = new DSPSignalNotification(m_sampleRate, m_centerFrequency);
sink->pushMessage(msg);
// start the sink:
if(m_state == State::StRunning) {
sink->start();
}
}
else if (DSPRemoveBasebandSampleSink::match(message))
{
auto cmd = (const DSPRemoveBasebandSampleSink&) message;
BasebandSampleSink* sink = cmd.getSampleSink();
if(m_state == State::StRunning) {
sink->stop();
}
m_basebandSampleSinks.remove(sink);
}
return false;
}
void DSPDeviceSourceEngine::handleInputMessages()
{
Message* message;
while ((message = m_inputMessageQueue.pop()) != nullptr)
{
qDebug("DSPDeviceSourceEngine::handleInputMessages: message: %s", message->getIdentifier());
if (handleMessage(*message)) {
delete message;
}
}

View File

@ -22,24 +22,23 @@
#ifndef INCLUDE_DSPDEVICEENGINE_H
#define INCLUDE_DSPDEVICEENGINE_H
#include <QThread>
#include <QObject>
#include <QTimer>
#include <QMutex>
#include <QWaitCondition>
#include "dsp/dsptypes.h"
#include "util/messagequeue.h"
#include "util/syncmessenger.h"
#include "export.h"
#include "util/movingaverage.h"
class DeviceSampleSource;
class BasebandSampleSink;
class SDRBASE_API DSPDeviceSourceEngine : public QThread {
class SDRBASE_API DSPDeviceSourceEngine : public QObject {
Q_OBJECT
public:
enum State {
enum class State {
StNotStarted, //!< engine is before initialization
StIdle, //!< engine is idle
StReady, //!< engine is ready to run
@ -47,17 +46,14 @@ public:
StError //!< engine is in error
};
DSPDeviceSourceEngine(uint uid, QObject* parent = NULL);
~DSPDeviceSourceEngine();
DSPDeviceSourceEngine(uint uid, QObject* parent = nullptr);
~DSPDeviceSourceEngine() final;
uint getUID() const { return m_uid; }
MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
void start(); //!< This thread start
void stop(); //!< This thread stop
bool initAcquisition(); //!< Initialize acquisition sequence
bool initAcquisition() const; //!< Initialize acquisition sequence
bool startAcquisition(); //!< Start acquisition sequence
void stopAcquistion(); //!< Stop acquisition sequence
@ -72,14 +68,13 @@ public:
State state() const { return m_state; } //!< Return DSP engine current state
QString errorMessage(); //!< Return the current error message
QString sourceDeviceDescription(); //!< Return the source device description
QString errorMessage() const; //!< Return the current error message
QString sourceDeviceDescription() const; //!< Return the source device description
private:
uint m_uid; //!< unique ID
MessageQueue m_inputMessageQueue; //<! Input message queue. Post here.
SyncMessenger m_syncMessenger; //!< Used to process messages synchronously with the thread
State m_state;
@ -89,7 +84,7 @@ private:
DeviceSampleSource* m_deviceSampleSource;
int m_sampleSourceSequence;
typedef std::list<BasebandSampleSink*> BasebandSampleSinks;
using BasebandSampleSinks = std::list<BasebandSampleSink *>;
BasebandSampleSinks m_basebandSampleSinks; //!< sample sinks within main thread (usually spectrum, file output)
uint m_sampleRate;
@ -98,7 +93,8 @@ private:
bool m_dcOffsetCorrection;
bool m_iqImbalanceCorrection;
double m_iOffset, m_qOffset;
double m_iOffset;
double m_qOffset;
MovingAverageUtil<int32_t, int64_t, 1024> m_iBeta;
MovingAverageUtil<int32_t, int64_t, 1024> m_qBeta;
@ -126,8 +122,6 @@ private:
qint32 m_qRange;
qint32 m_imbalance;
void run();
void iqCorrections(SampleVector::iterator begin, SampleVector::iterator end, bool imbalanceCorrection);
void dcOffset(SampleVector::iterator begin, SampleVector::iterator end);
void imbalance(SampleVector::iterator begin, SampleVector::iterator end);
@ -140,11 +134,11 @@ private:
void setState(State state);
void handleSetSource(DeviceSampleSource* source); //!< Manage source setting
bool handleMessage(const Message& cmd);
private slots:
void handleData(); //!< Handle data when samples from source FIFO are ready to be processed
void handleInputMessages(); //!< Handle input message queue
void handleSynchronousMessages(); //!< Handle synchronous messages with the thread
signals:
void stateChanged();

View File

@ -42,7 +42,7 @@ DSPEngine::DSPEngine() :
DSPEngine::~DSPEngine()
{
QList<DSPDeviceSourceEngine*>::iterator it = m_deviceSourceEngines.begin();
auto it = m_deviceSourceEngines.begin();
while (it != m_deviceSourceEngines.end())
{
@ -63,24 +63,45 @@ DSPEngine *DSPEngine::instance()
DSPDeviceSourceEngine *DSPEngine::addDeviceSourceEngine()
{
m_deviceSourceEngines.push_back(new DSPDeviceSourceEngine(m_deviceSourceEnginesUIDSequence));
auto *deviceSourceEngine = new DSPDeviceSourceEngine(m_deviceSourceEnginesUIDSequence);
auto *deviceThread = new QThread();
m_deviceSourceEnginesUIDSequence++;
m_deviceEngineReferences.push_back(DeviceEngineReference{0, m_deviceSourceEngines.back(), nullptr, nullptr});
return m_deviceSourceEngines.back();
m_deviceSourceEngines.push_back(deviceSourceEngine);
m_deviceEngineReferences.push_back(DeviceEngineReference{0, m_deviceSourceEngines.back(), nullptr, nullptr, deviceThread});
deviceSourceEngine->moveToThread(deviceThread);
QObject::connect(
deviceThread,
&QThread::finished,
deviceSourceEngine,
&QObject::deleteLater
);
QObject::connect(
deviceThread,
&QThread::finished,
deviceThread,
&QThread::deleteLater
);
deviceThread->start();
return deviceSourceEngine;
}
void DSPEngine::removeLastDeviceSourceEngine()
{
if (m_deviceSourceEngines.size() > 0)
if (!m_deviceSourceEngines.empty())
{
DSPDeviceSourceEngine *lastDeviceEngine = m_deviceSourceEngines.back();
delete lastDeviceEngine;
const DSPDeviceSourceEngine *lastDeviceEngine = m_deviceSourceEngines.back();
m_deviceSourceEngines.pop_back();
for (int i = 0; i < m_deviceEngineReferences.size(); i++)
{
if (m_deviceEngineReferences[i].m_deviceSourceEngine == lastDeviceEngine)
{
QThread* deviceThread = m_deviceEngineReferences[i].m_thread;
deviceThread->exit();
deviceThread->wait();
m_deviceEngineReferences.removeAt(i);
break;
}
@ -90,24 +111,45 @@ void DSPEngine::removeLastDeviceSourceEngine()
DSPDeviceSinkEngine *DSPEngine::addDeviceSinkEngine()
{
m_deviceSinkEngines.push_back(new DSPDeviceSinkEngine(m_deviceSinkEnginesUIDSequence));
auto *deviceSinkEngine = new DSPDeviceSinkEngine(m_deviceSinkEnginesUIDSequence);
auto *deviceThread = new QThread();
m_deviceSinkEnginesUIDSequence++;
m_deviceEngineReferences.push_back(DeviceEngineReference{1, nullptr, m_deviceSinkEngines.back(), nullptr});
return m_deviceSinkEngines.back();
m_deviceSinkEngines.push_back(deviceSinkEngine);
m_deviceEngineReferences.push_back(DeviceEngineReference{1, nullptr, m_deviceSinkEngines.back(), nullptr, deviceThread});
deviceSinkEngine->moveToThread(deviceThread);
QObject::connect(
deviceThread,
&QThread::finished,
deviceSinkEngine,
&QObject::deleteLater
);
QObject::connect(
deviceThread,
&QThread::finished,
deviceThread,
&QThread::deleteLater
);
deviceThread->start();
return deviceSinkEngine;
}
void DSPEngine::removeLastDeviceSinkEngine()
{
if (m_deviceSinkEngines.size() > 0)
if (!m_deviceSinkEngines.empty())
{
DSPDeviceSinkEngine *lastDeviceEngine = m_deviceSinkEngines.back();
delete lastDeviceEngine;
const DSPDeviceSinkEngine *lastDeviceEngine = m_deviceSinkEngines.back();
m_deviceSinkEngines.pop_back();
for (int i = 0; i < m_deviceEngineReferences.size(); i++)
{
if (m_deviceEngineReferences[i].m_deviceSinkEngine == lastDeviceEngine)
{
QThread* deviceThread = m_deviceEngineReferences[i].m_thread;
deviceThread->exit();
deviceThread->wait();
m_deviceEngineReferences.removeAt(i);
break;
}
@ -117,24 +159,45 @@ void DSPEngine::removeLastDeviceSinkEngine()
DSPDeviceMIMOEngine *DSPEngine::addDeviceMIMOEngine()
{
m_deviceMIMOEngines.push_back(new DSPDeviceMIMOEngine(m_deviceMIMOEnginesUIDSequence));
auto *deviceMIMOEngine = new DSPDeviceMIMOEngine(m_deviceMIMOEnginesUIDSequence);
auto *deviceThread = new QThread();
m_deviceMIMOEnginesUIDSequence++;
m_deviceEngineReferences.push_back(DeviceEngineReference{2, nullptr, nullptr, m_deviceMIMOEngines.back()});
return m_deviceMIMOEngines.back();
m_deviceMIMOEngines.push_back(deviceMIMOEngine);
m_deviceEngineReferences.push_back(DeviceEngineReference{2, nullptr, nullptr, m_deviceMIMOEngines.back(), deviceThread});
deviceMIMOEngine->moveToThread(deviceThread);
QObject::connect(
deviceThread,
&QThread::finished,
deviceMIMOEngine,
&QObject::deleteLater
);
QObject::connect(
deviceThread,
&QThread::finished,
deviceThread,
&QThread::deleteLater
);
deviceThread->start();
return deviceMIMOEngine;
}
void DSPEngine::removeLastDeviceMIMOEngine()
{
if (m_deviceMIMOEngines.size() > 0)
if (!m_deviceMIMOEngines.empty())
{
DSPDeviceMIMOEngine *lastDeviceEngine = m_deviceMIMOEngines.back();
delete lastDeviceEngine;
const DSPDeviceMIMOEngine *lastDeviceEngine = m_deviceMIMOEngines.back();
m_deviceMIMOEngines.pop_back();
for (int i = 0; i < m_deviceEngineReferences.size(); i++)
{
if (m_deviceEngineReferences[i].m_deviceMIMOEngine == lastDeviceEngine)
{
QThread* deviceThread = m_deviceEngineReferences[i].m_thread;
deviceThread->exit();
deviceThread->wait();
m_deviceEngineReferences.removeAt(i);
break;
}
@ -151,19 +214,25 @@ void DSPEngine::removeDeviceEngineAt(int deviceIndex)
if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 0) // source
{
DSPDeviceSourceEngine *deviceEngine = m_deviceEngineReferences[deviceIndex].m_deviceSourceEngine;
delete deviceEngine;
QThread *deviceThread = m_deviceEngineReferences[deviceIndex].m_thread;
deviceThread->exit();
deviceThread->wait();
m_deviceSourceEngines.removeAll(deviceEngine);
}
else if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 1) // sink
{
DSPDeviceSinkEngine *deviceEngine = m_deviceEngineReferences[deviceIndex].m_deviceSinkEngine;
delete deviceEngine;
QThread *deviceThread = m_deviceEngineReferences[deviceIndex].m_thread;
deviceThread->exit();
deviceThread->wait();
m_deviceSinkEngines.removeAll(deviceEngine);
}
else if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 2) // MIMO
{
DSPDeviceMIMOEngine *deviceEngine = m_deviceEngineReferences[deviceIndex].m_deviceMIMOEngine;
delete deviceEngine;
QThread *deviceThread = m_deviceEngineReferences[deviceIndex].m_thread;
deviceThread->exit();
deviceThread->wait();
m_deviceMIMOEngines.removeAll(deviceEngine);
}

View File

@ -32,6 +32,7 @@ class DSPDeviceSourceEngine;
class DSPDeviceSinkEngine;
class DSPDeviceMIMOEngine;
class FFTFactory;
class QThread;
class SDRBASE_API DSPEngine : public QObject {
Q_OBJECT
@ -79,6 +80,7 @@ private:
DSPDeviceSourceEngine *m_deviceSourceEngine;
DSPDeviceSinkEngine *m_deviceSinkEngine;
DSPDeviceMIMOEngine *m_deviceMIMOEngine;
QThread *m_thread;
};
QList<DSPDeviceSourceEngine*> m_deviceSourceEngines;

View File

@ -84,8 +84,8 @@ public:
StreamType streamType; //!< This is the type of stream supported
int deviceNbItems; //!< Number of items (or streams) in the device. >1 for composite devices.
int deviceItemIndex; //!< For composite devices this is the Rx or Tx stream index. -1 if not initialized
int claimed; //!< This is the device set index if claimed else -1
bool removed; //!< Set if device has been removed
int claimed = -1; //!< This is the device set index if claimed else -1
bool removed = false; //!< Set if device has been removed
SamplingDevice(const QString& _displayedName,
const QString& _hardwareId,
@ -104,9 +104,7 @@ public:
type(_type),
streamType(_streamType),
deviceNbItems(_deviceNbItems),
deviceItemIndex(_deviceItemIndex),
claimed(-1),
removed(false)
deviceItemIndex(_deviceItemIndex)
{ }
bool operator==(const SamplingDevice& rhs) const
@ -117,7 +115,7 @@ public:
&& serial == rhs.serial;
}
};
typedef QList<SamplingDevice> SamplingDevices;
using SamplingDevices = QList<SamplingDevice>;
/** This is the device from which the sampling devices are derived. For physical devices this represents
* a single physical unit (a LimeSDR, HackRF, BladeRF, RTL-SDR dongle, ...) that is enumerated once and
@ -148,9 +146,9 @@ public:
nbTxStreams(_nbTxStreams)
{}
};
typedef QList<OriginDevice> OriginDevices;
using OriginDevices = QList<OriginDevice>;
virtual ~PluginInterface() { }
virtual ~PluginInterface() = default;
virtual const PluginDescriptor& getPluginDescriptor() const = 0;
virtual void initPlugin(PluginAPI* pluginAPI) = 0;

View File

@ -78,10 +78,7 @@ DeviceUISet::DeviceUISet(int deviceSetIndex, DeviceSet *deviceSet)
DeviceUISet::~DeviceUISet()
{
// delete m_channelWindow;
delete m_mainSpectrumGUI;
// delete m_spectrumGUI; // done above
// delete m_spectrum;
}
void DeviceUISet::setIndex(int deviceSetIndex)
@ -119,7 +116,7 @@ void DeviceUISet::registerRxChannelInstance(ChannelAPI *channelAPI, ChannelGUI*
channelGUI,
&ChannelGUI::closing,
this,
[=](){ this->handleChannelGUIClosing(channelGUI); },
[this, channelGUI](){ this->handleChannelGUIClosing(channelGUI); },
Qt::QueuedConnection
);
}
@ -132,7 +129,7 @@ void DeviceUISet::registerTxChannelInstance(ChannelAPI *channelAPI, ChannelGUI*
channelGUI,
&ChannelGUI::closing,
this,
[=](){ this->handleChannelGUIClosing(channelGUI); },
[this, channelGUI](){ this->handleChannelGUIClosing(channelGUI); },
Qt::QueuedConnection
);
}
@ -145,7 +142,7 @@ void DeviceUISet::registerChannelInstance(ChannelAPI *channelAPI, ChannelGUI* ch
channelGUI,
&ChannelGUI::closing,
this,
[=](){ this->handleChannelGUIClosing(channelGUI); },
[this, channelGUI](){ this->handleChannelGUIClosing(channelGUI); },
Qt::QueuedConnection
);
}
@ -170,7 +167,7 @@ void DeviceUISet::freeChannels()
{
qDebug("DeviceUISet::freeChannels: destroying channel [%s]", qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI()));
m_channelInstanceRegistrations[i].m_gui->destroy();
m_channelInstanceRegistrations[i].m_channelAPI->destroy();
delete m_channelInstanceRegistrations[i].m_channelAPI;
}
m_channelInstanceRegistrations.clear();
@ -185,7 +182,7 @@ void DeviceUISet::deleteChannel(int channelIndex)
qPrintable(m_channelInstanceRegistrations[channelIndex].m_channelAPI->getURI()),
channelIndex);
m_channelInstanceRegistrations[channelIndex].m_gui->destroy();
m_channelInstanceRegistrations[channelIndex].m_channelAPI->destroy();
delete m_channelInstanceRegistrations[channelIndex].m_channelAPI;
m_channelInstanceRegistrations.removeAt(channelIndex);
}
@ -226,14 +223,14 @@ bool DeviceUISet::deserialize(const QByteArray& data)
if (d.getVersion() == 1)
{
QByteArray data;
QByteArray bdata;
d.readBlob(1, &data);
m_deviceAPI->deserialize(data);
d.readBlob(2, &data);
m_deviceGUI->deserialize(data);
d.readBlob(3, &data);
m_spectrumGUI->deserialize(data);
d.readBlob(1, &bdata);
m_deviceAPI->deserialize(bdata);
d.readBlob(2, &bdata);
m_deviceGUI->deserialize(bdata);
d.readBlob(3, &bdata);
m_spectrumGUI->deserialize(bdata);
return true;
}
@ -324,16 +321,16 @@ void DeviceUISet::loadRxChannelSettings(const Preset *preset, PluginAPI *pluginA
qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI()));
m_channelInstanceRegistrations[i].m_channelAPI->setMessageQueueToGUI(nullptr); // have channel stop sending messages to its GUI
m_channelInstanceRegistrations[i].m_gui->destroy();
m_channelInstanceRegistrations[i].m_channelAPI->destroy();
delete m_channelInstanceRegistrations[i].m_channelAPI;
}
m_channelInstanceRegistrations.clear();
m_deviceSet->clearChannels();
qDebug("DeviceUISet::loadRxChannelSettings: %d channel(s) in preset", preset->getChannelCount());
for (int i = 0; i < preset->getChannelCount(); i++)
for (int j = 0; j < preset->getChannelCount(); j++)
{
const Preset::ChannelConfig& channelConfig = preset->getChannelConfig(i);
const Preset::ChannelConfig& channelConfig = preset->getChannelConfig(j);
ChannelGUI *rxChannelGUI = nullptr;
ChannelAPI *channelAPI = nullptr;
@ -348,7 +345,7 @@ void DeviceUISet::loadRxChannelSettings(const Preset *preset, PluginAPI *pluginA
qPrintable((*channelRegistrations)[i].m_channelIdURI),
qPrintable(channelConfig.m_channelIdURI));
BasebandSampleSink *rxChannel = nullptr;
PluginInterface *pluginInterface = (*channelRegistrations)[i].m_plugin;
const PluginInterface *pluginInterface = (*channelRegistrations)[i].m_plugin;
pluginInterface->createRxChannel(m_deviceAPI, &rxChannel, &channelAPI);
rxChannelGUI = pluginInterface->createRxChannelGUI(this, rxChannel);
rxChannelGUI->setDisplayedame(pluginInterface->getPluginDescriptor().displayedName);
@ -357,7 +354,7 @@ void DeviceUISet::loadRxChannelSettings(const Preset *preset, PluginAPI *pluginA
rxChannelGUI,
&ChannelGUI::closing,
this,
[=](){ this->handleChannelGUIClosing(rxChannelGUI); },
[this, rxChannelGUI](){ this->handleChannelGUIClosing(rxChannelGUI); },
Qt::QueuedConnection
);
break;
@ -370,7 +367,7 @@ void DeviceUISet::loadRxChannelSettings(const Preset *preset, PluginAPI *pluginA
rxChannelGUI->deserialize(channelConfig.m_config);
int originalWorkspaceIndex = rxChannelGUI->getWorkspaceIndex();
if (workspaces && (workspaces->size() > 0) && (originalWorkspaceIndex < workspaces->size())) // restore in original workspace
if (workspaces && (!workspaces->empty()) && (originalWorkspaceIndex < workspaces->size())) // restore in original workspace
{
(*workspaces)[originalWorkspaceIndex]->addToMdiArea((QMdiSubWindow*) rxChannelGUI);
}
@ -395,19 +392,19 @@ void DeviceUISet::loadRxChannelSettings(const Preset *preset, PluginAPI *pluginA
rxChannelGUI,
&ChannelGUI::moveToWorkspace,
this,
[=](int wsIndexDest){ MainWindow::getInstance()->channelMove(rxChannelGUI, wsIndexDest); }
[rxChannelGUI](int wsIndexDest){ MainWindow::getInstance()->channelMove(rxChannelGUI, wsIndexDest); }
);
QObject::connect(
rxChannelGUI,
&ChannelGUI::duplicateChannelEmitted,
this,
[=](){ MainWindow::getInstance()->channelDuplicate(rxChannelGUI); }
[rxChannelGUI](){ MainWindow::getInstance()->channelDuplicate(rxChannelGUI); }
);
QObject::connect(
rxChannelGUI,
&ChannelGUI::moveToDeviceSet,
this,
[=](int dsIndexDest){ MainWindow::getInstance()->channelMoveToDeviceSet(rxChannelGUI, dsIndexDest); }
[rxChannelGUI](int dsIndexDest){ MainWindow::getInstance()->channelMoveToDeviceSet(rxChannelGUI, dsIndexDest); }
);
}
}
@ -453,16 +450,16 @@ void DeviceUISet::loadTxChannelSettings(const Preset *preset, PluginAPI *pluginA
qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI()));
m_channelInstanceRegistrations[i].m_channelAPI->setMessageQueueToGUI(nullptr); // have channel stop sending messages to its GUI
m_channelInstanceRegistrations[i].m_gui->destroy();
m_channelInstanceRegistrations[i].m_channelAPI->destroy();
delete m_channelInstanceRegistrations[i].m_channelAPI;
}
m_channelInstanceRegistrations.clear();
m_deviceSet->clearChannels();
qDebug("DeviceUISet::loadTxChannelSettings: %d channel(s) in preset", preset->getChannelCount());
for (int i = 0; i < preset->getChannelCount(); i++)
for (int j = 0; j < preset->getChannelCount(); j++)
{
const Preset::ChannelConfig& channelConfig = preset->getChannelConfig(i);
const Preset::ChannelConfig& channelConfig = preset->getChannelConfig(j);
ChannelGUI *txChannelGUI = nullptr;
ChannelAPI *channelAPI = nullptr;
@ -475,8 +472,8 @@ void DeviceUISet::loadTxChannelSettings(const Preset *preset, PluginAPI *pluginA
qDebug("DeviceUISet::loadTxChannelSettings: creating new channel [%s] from config [%s]",
qPrintable((*channelRegistrations)[i].m_channelIdURI),
qPrintable(channelConfig.m_channelIdURI));
BasebandSampleSource *txChannel;
PluginInterface *pluginInterface = (*channelRegistrations)[i].m_plugin;
BasebandSampleSource *txChannel = nullptr;
const PluginInterface *pluginInterface = (*channelRegistrations)[i].m_plugin;
pluginInterface->createTxChannel(m_deviceAPI, &txChannel, &channelAPI);
txChannelGUI = pluginInterface->createTxChannelGUI(this, txChannel);
txChannelGUI->setDisplayedame(pluginInterface->getPluginDescriptor().displayedName);
@ -485,7 +482,7 @@ void DeviceUISet::loadTxChannelSettings(const Preset *preset, PluginAPI *pluginA
txChannelGUI,
&ChannelGUI::closing,
this,
[=](){ this->handleChannelGUIClosing(txChannelGUI); },
[this, txChannelGUI](){ this->handleChannelGUIClosing(txChannelGUI); },
Qt::QueuedConnection
);
break;
@ -498,7 +495,7 @@ void DeviceUISet::loadTxChannelSettings(const Preset *preset, PluginAPI *pluginA
txChannelGUI->deserialize(channelConfig.m_config);
int originalWorkspaceIndex = txChannelGUI->getWorkspaceIndex();
if (workspaces && (workspaces->size() > 0) && (originalWorkspaceIndex < workspaces->size())) // restore in original workspace
if (workspaces && (!workspaces->empty()) && (originalWorkspaceIndex < workspaces->size())) // restore in original workspace
{
(*workspaces)[originalWorkspaceIndex]->addToMdiArea((QMdiSubWindow*) txChannelGUI);
}
@ -523,19 +520,19 @@ void DeviceUISet::loadTxChannelSettings(const Preset *preset, PluginAPI *pluginA
txChannelGUI,
&ChannelGUI::moveToWorkspace,
this,
[=](int wsIndexDest){ MainWindow::getInstance()->channelMove(txChannelGUI, wsIndexDest); }
[txChannelGUI](int wsIndexDest){ MainWindow::getInstance()->channelMove(txChannelGUI, wsIndexDest); }
);
QObject::connect(
txChannelGUI,
&ChannelGUI::duplicateChannelEmitted,
this,
[=](){ MainWindow::getInstance()->channelDuplicate(txChannelGUI); }
[txChannelGUI](){ MainWindow::getInstance()->channelDuplicate(txChannelGUI); }
);
QObject::connect(
txChannelGUI,
&ChannelGUI::moveToDeviceSet,
this,
[=](int dsIndexDest){ MainWindow::getInstance()->channelMoveToDeviceSet(txChannelGUI, dsIndexDest); }
[txChannelGUI](int dsIndexDest){ MainWindow::getInstance()->channelMoveToDeviceSet(txChannelGUI, dsIndexDest); }
);
}
}
@ -579,16 +576,16 @@ void DeviceUISet::loadMIMOChannelSettings(const Preset *preset, PluginAPI *plugi
qDebug("DeviceUISet::loadMIMOChannelSettings: destroying old channel [%s]",
qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI()));
m_channelInstanceRegistrations[i].m_gui->destroy(); // stop GUI first (issue #1427)
m_channelInstanceRegistrations[i].m_channelAPI->destroy(); // stop channel before (issue #860)
delete m_channelInstanceRegistrations[i].m_channelAPI; // stop channel before (issue #860)
}
m_channelInstanceRegistrations.clear();
m_deviceSet->clearChannels();
qDebug("DeviceUISet::loadMIMOChannelSettings: %d channel(s) in preset", preset->getChannelCount());
for (int i = 0; i < preset->getChannelCount(); i++)
for (int j = 0; j < preset->getChannelCount(); j++)
{
const Preset::ChannelConfig& channelConfig = preset->getChannelConfig(i);
const Preset::ChannelConfig& channelConfig = preset->getChannelConfig(j);
ChannelGUI *channelGUI = nullptr;
ChannelAPI *channelAPI = nullptr;
@ -602,8 +599,8 @@ void DeviceUISet::loadMIMOChannelSettings(const Preset *preset, PluginAPI *plugi
qDebug("DeviceUISet::loadMIMOChannelSettings: creating new MIMO channel [%s] from config [%s]",
qPrintable((*channelMIMORegistrations)[i].m_channelIdURI),
qPrintable(channelConfig.m_channelIdURI));
MIMOChannel *mimoChannel;
PluginInterface *pluginInterface = (*channelMIMORegistrations)[i].m_plugin;
MIMOChannel *mimoChannel = nullptr;
const PluginInterface *pluginInterface = (*channelMIMORegistrations)[i].m_plugin;
pluginInterface->createMIMOChannel(m_deviceAPI, &mimoChannel, &channelAPI);
channelGUI = pluginInterface->createMIMOChannelGUI(this, mimoChannel);
channelGUI->setDisplayedame(pluginInterface->getPluginDescriptor().displayedName);
@ -612,7 +609,7 @@ void DeviceUISet::loadMIMOChannelSettings(const Preset *preset, PluginAPI *plugi
channelGUI,
&ChannelGUI::closing,
this,
[=](){ this->handleChannelGUIClosing(channelGUI); },
[this, channelGUI](){ this->handleChannelGUIClosing(channelGUI); },
Qt::QueuedConnection
);
break;
@ -629,8 +626,8 @@ void DeviceUISet::loadMIMOChannelSettings(const Preset *preset, PluginAPI *plugi
qDebug("DeviceUISet::loadMIMOChannelSettings: creating new Rx channel [%s] from config [%s]",
qPrintable((*channelRxRegistrations)[i].m_channelIdURI),
qPrintable(channelConfig.m_channelIdURI));
BasebandSampleSink *rxChannel;
PluginInterface *pluginInterface = (*channelRxRegistrations)[i].m_plugin;
BasebandSampleSink *rxChannel = nullptr;
const PluginInterface *pluginInterface = (*channelRxRegistrations)[i].m_plugin;
pluginInterface->createRxChannel(m_deviceAPI, &rxChannel, &channelAPI);
channelGUI = pluginInterface->createRxChannelGUI(this, rxChannel);
channelGUI->setDisplayedame(pluginInterface->getPluginDescriptor().displayedName);
@ -639,7 +636,7 @@ void DeviceUISet::loadMIMOChannelSettings(const Preset *preset, PluginAPI *plugi
channelGUI,
&ChannelGUI::closing,
this,
[=](){ this->handleChannelGUIClosing(channelGUI); },
[this, channelGUI](){ this->handleChannelGUIClosing(channelGUI); },
Qt::QueuedConnection
);
break;
@ -656,8 +653,8 @@ void DeviceUISet::loadMIMOChannelSettings(const Preset *preset, PluginAPI *plugi
qDebug("DeviceUISet::loadMIMOChannelSettings: creating new Tx channel [%s] from config [%s]",
qPrintable((*channelTxRegistrations)[i].m_channelIdURI),
qPrintable(channelConfig.m_channelIdURI));
BasebandSampleSource *txChannel;
PluginInterface *pluginInterface = (*channelTxRegistrations)[i].m_plugin;
BasebandSampleSource *txChannel = nullptr;
const PluginInterface *pluginInterface = (*channelTxRegistrations)[i].m_plugin;
pluginInterface->createTxChannel(m_deviceAPI, &txChannel, &channelAPI);
channelGUI = pluginInterface->createTxChannelGUI(this, txChannel);
channelGUI->setDisplayedame(pluginInterface->getPluginDescriptor().displayedName);
@ -672,7 +669,7 @@ void DeviceUISet::loadMIMOChannelSettings(const Preset *preset, PluginAPI *plugi
channelGUI->deserialize(channelConfig.m_config);
int originalWorkspaceIndex = channelGUI->getWorkspaceIndex();
if (workspaces && (workspaces->size() > 0) && (originalWorkspaceIndex < workspaces->size())) // restore in original workspace
if (workspaces && (!workspaces->empty()) && (originalWorkspaceIndex < workspaces->size())) // restore in original workspace
{
(*workspaces)[originalWorkspaceIndex]->addToMdiArea((QMdiSubWindow*) channelGUI);
}
@ -697,26 +694,26 @@ void DeviceUISet::loadMIMOChannelSettings(const Preset *preset, PluginAPI *plugi
channelGUI,
&ChannelGUI::closing,
this,
[=](){ this->handleChannelGUIClosing(channelGUI); },
[this, channelGUI](){ this->handleChannelGUIClosing(channelGUI); },
Qt::QueuedConnection
);
QObject::connect(
channelGUI,
&ChannelGUI::moveToWorkspace,
this,
[=](int wsIndexDest){ MainWindow::getInstance()->channelMove(channelGUI, wsIndexDest); }
[channelGUI](int wsIndexDest){ MainWindow::getInstance()->channelMove(channelGUI, wsIndexDest); }
);
QObject::connect(
channelGUI,
&ChannelGUI::duplicateChannelEmitted,
this,
[=](){ MainWindow::getInstance()->channelDuplicate(channelGUI); }
[channelGUI](){ MainWindow::getInstance()->channelDuplicate(channelGUI); }
);
QObject::connect(
channelGUI,
&ChannelGUI::moveToDeviceSet,
this,
[=](int dsIndexDest){ MainWindow::getInstance()->channelMoveToDeviceSet(channelGUI, dsIndexDest); }
[channelGUI](int dsIndexDest){ MainWindow::getInstance()->channelMoveToDeviceSet(channelGUI, dsIndexDest); }
);
}
}
@ -766,11 +763,11 @@ bool DeviceUISet::ChannelInstanceRegistration::operator<(const ChannelInstanceRe
}
}
void DeviceUISet::handleChannelGUIClosing(ChannelGUI* channelGUI)
void DeviceUISet::handleChannelGUIClosing(const ChannelGUI* channelGUI)
{
qDebug("DeviceUISet::handleChannelGUIClosing: %s: %d", qPrintable(channelGUI->getTitle()), channelGUI->getIndex());
for (ChannelInstanceRegistrations::iterator it = m_channelInstanceRegistrations.begin(); it != m_channelInstanceRegistrations.end(); ++it)
for (auto it = m_channelInstanceRegistrations.begin(); it != m_channelInstanceRegistrations.end(); ++it)
{
if (it->m_gui == channelGUI)
{
@ -793,7 +790,7 @@ void DeviceUISet::handleChannelGUIClosing(ChannelGUI* channelGUI)
}
}
void DeviceUISet::handleDeleteChannel(ChannelAPI *channelAPI)
void DeviceUISet::handleDeleteChannel(ChannelAPI *channelAPI) const
{
channelAPI->destroy();
}

View File

@ -33,7 +33,6 @@ class SpectrumVis;
class GLSpectrum;
class GLSpectrumGUI;
class MainSpectrumGUI;
// class ChannelWindow;
class DeviceAPI;
class DeviceSet;
class DSPDeviceSourceEngine;
@ -61,7 +60,6 @@ public:
GLSpectrum *m_spectrum;
GLSpectrumGUI *m_spectrumGUI;
MainSpectrumGUI *m_mainSpectrumGUI;
// ChannelWindow *m_channelWindow;
DeviceAPI *m_deviceAPI;
DeviceGUI *m_deviceGUI;
DSPDeviceSourceEngine *m_deviceSourceEngine;
@ -74,7 +72,7 @@ public:
int m_selectedDeviceItemImdex;
DeviceUISet(int deviceSetIndex, DeviceSet *deviceSet);
~DeviceUISet();
~DeviceUISet() final;
void setIndex(int deviceSetIndex);
int getIndex() const { return m_deviceSetIndex; }
@ -146,10 +144,8 @@ private:
bool operator<(const ChannelInstanceRegistration& other) const;
};
typedef QList<ChannelInstanceRegistration> ChannelInstanceRegistrations;
using ChannelInstanceRegistrations = QList<ChannelInstanceRegistration>;
// ChannelInstanceRegistrations m_rxChannelInstanceRegistrations;
// ChannelInstanceRegistrations m_txChannelInstanceRegistrations;
ChannelInstanceRegistrations m_channelInstanceRegistrations;
int m_deviceSetIndex;
DeviceSet *m_deviceSet;
@ -165,8 +161,8 @@ private:
void saveMIMOChannelSettings(Preset* preset) const;
private slots:
void handleChannelGUIClosing(ChannelGUI* channelGUI);
void handleDeleteChannel(ChannelAPI *channelAPI);
void handleChannelGUIClosing(const ChannelGUI* channelGUI);
void handleDeleteChannel(ChannelAPI *channelAPI) const;
void onTimeSelected(int deviceSetIndex, float time);
};

File diff suppressed because it is too large Load Diff

View File

@ -69,27 +69,23 @@ class SerializableInterface;
class QMenuBar;
class Workspace;
// namespace Ui {
// class MainWindow;
// }
class SDRGUI_API MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parser, QWidget* parent = nullptr);
~MainWindow();
~MainWindow() final;
static MainWindow *getInstance() { return m_instance; } // Main Window is de facto a singleton so this just returns its reference
MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
const PluginManager *getPluginManager() const { return m_pluginManager; }
std::vector<DeviceUISet*>& getDeviceUISets() { return m_deviceUIs; }
void commandKeysConnect(QObject *object, const char *slot);
void commandKeysDisconnect(QObject *object, const char *slot);
void commandKeysConnect(const QObject *object, const char *slot);
void commandKeysDisconnect(const QObject *object, const char *slot) const;
int getNumberOfWorkspaces() const { return m_workspaces.size(); }
public slots:
void channelMove(ChannelGUI *gui, int wsIndexDestination);
void channelDuplicate(ChannelGUI *gui);
void channelDuplicate(const ChannelGUI *gui);
void channelMoveToDeviceSet(ChannelGUI *gui, int dsIndexDestination);
private:
@ -108,7 +104,6 @@ private:
static MainWindow *m_instance;
QList<Workspace*> m_workspaces;
Workspace *m_currentWorkspace;
// Ui::MainWindow* ui;
MessageQueue m_inputMessageQueue;
MainCore *m_mainCore;
std::vector<DeviceUISet*> m_deviceUIs;
@ -143,10 +138,10 @@ private:
void loadFeatureSetPresetSettings(const FeatureSetPreset* preset, int featureSetIndex, Workspace *workspace);
void saveFeatureSetPresetSettings(FeatureSetPreset* preset, int featureSetIndex);
QString openGLVersion();
void createMenuBar(QToolButton *button);
QString openGLVersion() const;
void createMenuBar(QToolButton *button) const;
void createStatusBar();
void closeEvent(QCloseEvent*);
void closeEvent(QCloseEvent*) final;
void applySettings();
void removeDeviceSet(int deviceSetIndex);
@ -155,7 +150,7 @@ private:
void removeFeatureSet(unsigned int featureSetIndex);
void removeAllFeatureSets();
void deleteChannel(int deviceSetIndex, int channelIndex);
void channelDuplicateToDeviceSet(ChannelGUI *sourceChannelGUI, int dsIndexDestination);
void channelDuplicateToDeviceSet(const ChannelGUI *sourceChannelGUI, int dsIndexDestination);
void sampleDeviceChange(int deviceType, int deviceSetIndex, int newDeviceIndex, Workspace *workspace);
void sampleSourceChange(int deviceSetIndex, int newDeviceIndex, Workspace *workspace);
void sampleSinkChange(int deviceSetIndex, int newDeviceIndex, Workspace *workspace);
@ -181,7 +176,7 @@ private:
bool handleMessage(const Message& cmd);
protected:
virtual void keyPressEvent(QKeyEvent* event) override;
void keyPressEvent(QKeyEvent* event) override;
private slots:
void handleMessages();
@ -202,39 +197,39 @@ private slots:
void on_action_My_Position_triggered();
void on_action_DeviceUserArguments_triggered();
void on_action_commands_triggered();
void on_action_Quick_Start_triggered();
void on_action_Main_Window_triggered();
void on_action_Quick_Start_triggered() const;
void on_action_Main_Window_triggered() const;
void on_action_Loaded_Plugins_triggered();
void on_action_About_triggered();
void updateStatus();
void addWorkspace();
void viewAllWorkspaces();
void viewAllWorkspaces() const;
void removeEmptyWorkspaces();
void openConfigurationDialog(bool openOnly);
void loadDefaultConfigurations();
void loadDefaultConfigurations() const;
void loadConfiguration(const Configuration *configuration, bool fromDialog = false);
void saveConfiguration(Configuration *configuration);
void sampleSourceAdd(Workspace *deviceWorkspace, Workspace *spectrumWorkspace, int deviceIndex);
void sampleSinkAdd(Workspace *workspace, Workspace *spectrumWorkspace, int deviceIndex);
void sampleMIMOAdd(Workspace *workspace, Workspace *spectrumWorkspace, int deviceIndex);
void samplingDeviceChangeHandler(DeviceGUI *deviceGUI, int newDeviceIndex);
void samplingDeviceChangeHandler(const DeviceGUI *deviceGUI, int newDeviceIndex);
void channelAddClicked(Workspace *workspace, int deviceSetIndex, int channelPluginIndex);
void featureAddClicked(Workspace *workspace, int featureIndex);
void featureMove(FeatureGUI *gui, int wsIndexDestnation);
void deviceStateChanged(DeviceAPI *deviceAPI);
void openFeaturePresetsDialog(QPoint p, Workspace *workspace);
void startAllDevices(Workspace *workspace);
void stopAllDevices(Workspace *workspace);
void startAllDevices(const Workspace *workspace) const;
void stopAllDevices(const Workspace *workspace) const;
void deviceMove(DeviceGUI *gui, int wsIndexDestnation);
void mainSpectrumMove(MainSpectrumGUI *gui, int wsIndexDestnation);
void mainSpectrumShow(int deviceSetIndex);
void mainSpectrumRequestDeviceCenterFrequency(int deviceSetIndex, qint64 deviceCenterFrequency);
void showAllChannels(int deviceSetIndex);
void openDeviceSetPresetsDialog(QPoint p, DeviceGUI *deviceGUI);
void commandKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifiers, bool release);
void openDeviceSetPresetsDialog(QPoint p, const DeviceGUI *deviceGUI);
void commandKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifiers, bool release) const;
void fftWisdomProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void orientationChanged(Qt::ScreenOrientation orientation);
void orientationChanged(Qt::ScreenOrientation orientation) const;
};
#endif // INCLUDE_MAINWINDOW_H

View File

@ -27,6 +27,9 @@
#include "dsp/dspdevicesourceengine.h"
#include "dsp/dspdevicesinkengine.h"
#include "dsp/dspdevicemimoengine.h"
#include "dsp/devicesamplesource.h"
#include "dsp/devicesamplesink.h"
#include "dsp/devicesamplemimo.h"
#include "dsp/spectrumvis.h"
#include "device/deviceapi.h"
#include "device/deviceset.h"
@ -40,7 +43,7 @@
#include "mainparser.h"
#include "mainserver.h"
MainServer *MainServer::m_instance = 0;
MainServer *MainServer::m_instance = nullptr;
MainServer::MainServer(qtwebapp::LoggerWithFile *logger, const MainParser& parser, QObject *parent) :
QObject(parent),
@ -71,7 +74,7 @@ MainServer::MainServer(qtwebapp::LoggerWithFile *logger, const MainParser& parse
loadSettings();
qDebug() << "MainServer::MainServer: finishing...";
QString applicationDirPath = QCoreApplication::instance()->applicationDirPath();
QString applicationDirPath = QCoreApplication::applicationDirPath();
m_apiAdapter = new WebAPIAdapter();
m_requestMapper = new WebAPIRequestMapper(this);
@ -86,7 +89,7 @@ MainServer::MainServer(qtwebapp::LoggerWithFile *logger, const MainParser& parse
MainServer::~MainServer()
{
while (m_mainCore->m_deviceSets.size() > 0) {
while (!m_mainCore->m_deviceSets.empty()) {
removeLastDevice();
}
@ -105,7 +108,7 @@ bool MainServer::handleMessage(const Message& cmd)
{
if (MainCore::MsgDeleteInstance::match(cmd))
{
while (m_mainCore->m_deviceSets.size() > 0)
while (!m_mainCore->m_deviceSets.empty())
{
removeLastDevice();
}
@ -115,13 +118,13 @@ bool MainServer::handleMessage(const Message& cmd)
}
else if (MainCore::MsgLoadPreset::match(cmd))
{
MainCore::MsgLoadPreset& notif = (MainCore::MsgLoadPreset&) cmd;
auto& notif = (const MainCore::MsgLoadPreset&) cmd;
loadPresetSettings(notif.getPreset(), notif.getDeviceSetIndex());
return true;
}
else if (MainCore::MsgSavePreset::match(cmd))
{
MainCore::MsgSavePreset& notif = (MainCore::MsgSavePreset&) cmd;
auto& notif = (const MainCore::MsgSavePreset&) cmd;
savePresetSettings(notif.getPreset(), notif.getDeviceSetIndex());
m_mainCore->m_settings.sortPresets();
m_mainCore->m_settings.save();
@ -129,7 +132,7 @@ bool MainServer::handleMessage(const Message& cmd)
}
else if (MainCore::MsgDeletePreset::match(cmd))
{
MainCore::MsgDeletePreset& notif = (MainCore::MsgDeletePreset&) cmd;
auto& notif = (const MainCore::MsgDeletePreset&) cmd;
const Preset *presetToDelete = notif.getPreset();
// remove preset from settings
m_mainCore->m_settings.deletePreset(presetToDelete);
@ -137,7 +140,7 @@ bool MainServer::handleMessage(const Message& cmd)
}
else if (MainCore::MsgDeleteConfiguration::match(cmd))
{
MainCore::MsgDeleteConfiguration& notif = (MainCore::MsgDeleteConfiguration&) cmd;
auto& notif = (const MainCore::MsgDeleteConfiguration&) cmd;
const Configuration *configuationToDelete = notif.getConfiguration();
// remove configuration from settings
m_mainCore->m_settings.deleteConfiguration(configuationToDelete);
@ -145,13 +148,13 @@ bool MainServer::handleMessage(const Message& cmd)
}
else if (MainCore::MsgLoadFeatureSetPreset::match(cmd))
{
MainCore::MsgLoadFeatureSetPreset& notif = (MainCore::MsgLoadFeatureSetPreset&) cmd;
auto& notif = (const MainCore::MsgLoadFeatureSetPreset&) cmd;
loadFeatureSetPresetSettings(notif.getPreset(), notif.getFeatureSetIndex());
return true;
}
else if (MainCore::MsgSaveFeatureSetPreset::match(cmd))
{
MainCore::MsgSaveFeatureSetPreset& notif = (MainCore::MsgSaveFeatureSetPreset&) cmd;
auto& notif = (const MainCore::MsgSaveFeatureSetPreset&) cmd;
saveFeatureSetPresetSettings(notif.getPreset(), notif.getFeatureSetIndex());
m_mainCore->m_settings.sortPresets();
m_mainCore->m_settings.save();
@ -159,7 +162,7 @@ bool MainServer::handleMessage(const Message& cmd)
}
else if (MainCore::MsgDeleteFeatureSetPreset::match(cmd))
{
MainCore::MsgDeleteFeatureSetPreset& notif = (MainCore::MsgDeleteFeatureSetPreset&) cmd;
auto& notif = (const MainCore::MsgDeleteFeatureSetPreset&) cmd;
const FeatureSetPreset *presetToDelete = notif.getPreset();
// remove preset from settings
m_mainCore->m_settings.deleteFeatureSetPreset(presetToDelete);
@ -167,7 +170,7 @@ bool MainServer::handleMessage(const Message& cmd)
}
else if (MainCore::MsgAddDeviceSet::match(cmd))
{
MainCore::MsgAddDeviceSet& notif = (MainCore::MsgAddDeviceSet&) cmd;
auto& notif = (const MainCore::MsgAddDeviceSet&) cmd;
int direction = notif.getDirection();
if (direction == 1) { // Single stream Tx
@ -182,7 +185,7 @@ bool MainServer::handleMessage(const Message& cmd)
}
else if (MainCore::MsgRemoveLastDeviceSet::match(cmd))
{
if (m_mainCore->m_deviceSets.size() > 0) {
if (!m_mainCore->m_deviceSets.empty()) {
removeLastDevice();
}
@ -190,7 +193,7 @@ bool MainServer::handleMessage(const Message& cmd)
}
else if (MainCore::MsgSetDevice::match(cmd))
{
MainCore::MsgSetDevice& notif = (MainCore::MsgSetDevice&) cmd;
auto& notif = (const MainCore::MsgSetDevice&) cmd;
if (notif.getDeviceType() == 1) {
changeSampleSink(notif.getDeviceSetIndex(), notif.getDeviceIndex());
@ -203,26 +206,26 @@ bool MainServer::handleMessage(const Message& cmd)
}
else if (MainCore::MsgAddChannel::match(cmd))
{
MainCore::MsgAddChannel& notif = (MainCore::MsgAddChannel&) cmd;
auto& notif = (const MainCore::MsgAddChannel&) cmd;
addChannel(notif.getDeviceSetIndex(), notif.getChannelRegistrationIndex());
return true;
}
else if (MainCore::MsgDeleteChannel::match(cmd))
{
MainCore::MsgDeleteChannel& notif = (MainCore::MsgDeleteChannel&) cmd;
auto& notif = (const MainCore::MsgDeleteChannel&) cmd;
deleteChannel(notif.getDeviceSetIndex(), notif.getChannelIndex());
return true;
}
else if (MainCore::MsgAddFeature::match(cmd))
{
MainCore::MsgAddFeature& notif = (MainCore::MsgAddFeature&) cmd;
auto& notif = (const MainCore::MsgAddFeature&) cmd;
addFeature(0, notif.getFeatureRegistrationIndex());
return true;
}
else if (MainCore::MsgDeleteFeature::match(cmd))
{
MainCore::MsgDeleteFeature& notif = (MainCore::MsgDeleteFeature&) cmd;
auto& notif = (const MainCore::MsgDeleteFeature&) cmd;
deleteFeature(0, notif.getFeatureIndex());
return true;
}
@ -241,7 +244,7 @@ void MainServer::handleMessages()
{
Message* message;
while ((message = m_inputMessageQueue.pop()) != 0)
while ((message = m_inputMessageQueue.pop()) != nullptr)
{
qDebug("MainServer::handleMessages: message: %s", message->getIdentifier());
handleMessage(*message);
@ -267,23 +270,15 @@ void MainServer::applySettings()
void MainServer::addSinkDevice()
{
DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine();
dspDeviceSinkEngine->start();
uint dspDeviceSinkEngineUID = dspDeviceSinkEngine->getUID();
char uidCStr[16];
sprintf(uidCStr, "UID:%d", dspDeviceSinkEngineUID);
int deviceTabIndex = m_mainCore->m_deviceSets.size();
auto deviceTabIndex = (int) m_mainCore->m_deviceSets.size();
m_mainCore->m_deviceSets.push_back(new DeviceSet(deviceTabIndex, 1));
m_mainCore->m_deviceSets.back()->m_deviceSourceEngine = nullptr;
m_mainCore->m_deviceSets.back()->m_deviceSinkEngine = dspDeviceSinkEngine;
m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine = nullptr;
dspDeviceSinkEngine->addSpectrumSink(m_mainCore->m_deviceSets.back()->m_spectrumVis);
char tabNameCStr[16];
sprintf(tabNameCStr, "T%d", deviceTabIndex);
DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamSingleTx, deviceTabIndex, nullptr, dspDeviceSinkEngine, nullptr);
auto *deviceAPI = new DeviceAPI(DeviceAPI::StreamSingleTx, deviceTabIndex, nullptr, dspDeviceSinkEngine, nullptr);
m_mainCore->m_deviceSets.back()->m_deviceAPI = deviceAPI;
QList<QString> channelNames;
@ -315,23 +310,15 @@ void MainServer::addSinkDevice()
void MainServer::addSourceDevice()
{
DSPDeviceSourceEngine *dspDeviceSourceEngine = m_dspEngine->addDeviceSourceEngine();
dspDeviceSourceEngine->start();
uint dspDeviceSourceEngineUID = dspDeviceSourceEngine->getUID();
char uidCStr[16];
sprintf(uidCStr, "UID:%d", dspDeviceSourceEngineUID);
int deviceTabIndex = m_mainCore->m_deviceSets.size();
auto deviceTabIndex = (int) m_mainCore->m_deviceSets.size();
m_mainCore->m_deviceSets.push_back(new DeviceSet(deviceTabIndex, 0));
m_mainCore->m_deviceSets.back()->m_deviceSourceEngine = dspDeviceSourceEngine;
m_mainCore->m_deviceSets.back()->m_deviceSinkEngine = nullptr;
m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine = nullptr;
dspDeviceSourceEngine->addSink(m_mainCore->m_deviceSets.back()->m_spectrumVis);
char tabNameCStr[16];
sprintf(tabNameCStr, "R%d", deviceTabIndex);
DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamSingleRx, deviceTabIndex, dspDeviceSourceEngine, nullptr, nullptr);
auto *deviceAPI = new DeviceAPI(DeviceAPI::StreamSingleRx, deviceTabIndex, dspDeviceSourceEngine, nullptr, nullptr);
m_mainCore->m_deviceSets.back()->m_deviceAPI = deviceAPI;
@ -362,23 +349,15 @@ void MainServer::addSourceDevice()
void MainServer::addMIMODevice()
{
DSPDeviceMIMOEngine *dspDeviceMIMOEngine = m_dspEngine->addDeviceMIMOEngine();
dspDeviceMIMOEngine->start();
uint dspDeviceMIMOEngineUID = dspDeviceMIMOEngine->getUID();
char uidCStr[16];
sprintf(uidCStr, "UID:%d", dspDeviceMIMOEngineUID);
int deviceTabIndex = m_mainCore->m_deviceSets.size();
auto deviceTabIndex = (int) m_mainCore->m_deviceSets.size();
m_mainCore->m_deviceSets.push_back(new DeviceSet(deviceTabIndex, 2));
m_mainCore->m_deviceSets.back()->m_deviceSourceEngine = nullptr;
m_mainCore->m_deviceSets.back()->m_deviceSinkEngine = nullptr;
m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine = dspDeviceMIMOEngine;
dspDeviceMIMOEngine->addSpectrumSink(m_mainCore->m_deviceSets.back()->m_spectrumVis);
char tabNameCStr[16];
sprintf(tabNameCStr, "M%d", deviceTabIndex);
DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamMIMO, deviceTabIndex, nullptr, nullptr, dspDeviceMIMOEngine);
auto *deviceAPI = new DeviceAPI(DeviceAPI::StreamMIMO, deviceTabIndex, nullptr, nullptr, dspDeviceMIMOEngine);
// create a test MIMO by default
int testMIMODeviceIndex = DeviceEnumerator::instance()->getTestMIMODeviceIndex();
@ -406,48 +385,48 @@ void MainServer::addMIMODevice()
void MainServer::removeLastDevice()
{
int removedTabIndex = m_mainCore->m_deviceSets.size() - 1;
auto removedTabIndex = (int) (m_mainCore->m_deviceSets.size() - 1);
if (m_mainCore->m_deviceSets.back()->m_deviceSourceEngine) // source set
{
DSPDeviceSourceEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceSourceEngine;
lastDeviceEngine->stopAcquistion();
// deletes old UI and input object
m_mainCore->m_deviceSets.back()->freeChannels(); // destroys the channel instances
m_mainCore->m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId();
m_mainCore->m_deviceSets.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceInput(
m_mainCore->m_deviceSets.back()->m_deviceAPI->getSampleSource());
m_mainCore->m_deviceSets.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
m_dspEngine->removeLastDeviceSourceEngine();
DeviceAPI *sourceAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI;
delete m_mainCore->m_deviceSets.back();
lastDeviceEngine->stop();
m_dspEngine->removeLastDeviceSourceEngine();
delete sourceAPI->getSampleSource();
delete sourceAPI;
}
else if (m_mainCore->m_deviceSets.back()->m_deviceSinkEngine) // sink set
{
DSPDeviceSinkEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceSinkEngine;
lastDeviceEngine->stopGeneration();
// deletes old UI and output object
m_mainCore->m_deviceSets.back()->freeChannels();
m_mainCore->m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId();
m_mainCore->m_deviceSets.back()->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput(
m_mainCore->m_deviceSets.back()->m_deviceAPI->getSampleSink());
m_mainCore->m_deviceSets.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
m_dspEngine->removeLastDeviceSinkEngine();
DeviceAPI *sinkAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI;
delete m_mainCore->m_deviceSets.back();
lastDeviceEngine->stop();
m_dspEngine->removeLastDeviceSinkEngine();
delete sinkAPI->getSampleSink();
delete sinkAPI;
}
else if (m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine) // MIMO set
{
m_mainCore->m_deviceSets.back()->freeChannels();
m_mainCore->m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId();
m_dspEngine->removeLastDeviceSourceEngine();
DeviceAPI *mimoAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI;
delete m_mainCore->m_deviceSets.back();
delete mimoAPI->getSampleMIMO();
delete mimoAPI;
}
m_mainCore->m_deviceSets.pop_back();
emit m_mainCore->deviceSetRemoved(removedTabIndex);
@ -494,21 +473,19 @@ void MainServer::changeSampleSource(int deviceSetIndex, int selectedDeviceIndex)
}
// add to buddies list
std::vector<DeviceSet*>::iterator it = m_mainCore->m_deviceSets.begin();
auto it = m_mainCore->m_deviceSets.begin();
int nbOfBuddies = 0;
for (; it != m_mainCore->m_deviceSets.end(); ++it)
{
if (*it != deviceSet) // do not add to itself
{
if ((deviceSet->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) &&
if ((*it != deviceSet) && // do not add to itself
(deviceSet->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) &&
(deviceSet->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial()))
{
(*it)->m_deviceAPI->addBuddy(deviceSet->m_deviceAPI);
nbOfBuddies++;
}
}
}
if (nbOfBuddies == 0) {
deviceSet->m_deviceAPI->setBuddyLeader(true);
@ -555,7 +532,7 @@ void MainServer::changeSampleSink(int deviceSetIndex, int selectedDeviceIndex)
{
qDebug("MainServer::changeSampleSink: non existent device replaced by File Sink");
int fileSinkDeviceIndex = DeviceEnumerator::instance()->getFileOutputDeviceIndex();
const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getTxSamplingDevice(fileSinkDeviceIndex);
samplingDevice = DeviceEnumerator::instance()->getTxSamplingDevice(fileSinkDeviceIndex);
deviceSet->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence);
deviceSet->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems);
deviceSet->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex);
@ -567,21 +544,19 @@ void MainServer::changeSampleSink(int deviceSetIndex, int selectedDeviceIndex)
}
// add to buddies list
std::vector<DeviceSet*>::iterator it = m_mainCore->m_deviceSets.begin();
auto it = m_mainCore->m_deviceSets.begin();
int nbOfBuddies = 0;
for (; it != m_mainCore->m_deviceSets.end(); ++it)
{
if (*it != deviceSet) // do not add to itself
{
if ((deviceSet->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) &&
(deviceSet->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial()))
(deviceSet->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial()) &&
(*it != deviceSet)) // do not add to itself
{
(*it)->m_deviceAPI->addBuddy(deviceSet->m_deviceAPI);
nbOfBuddies++;
}
}
}
if (nbOfBuddies == 0) {
deviceSet->m_deviceAPI->setBuddyLeader(true);
@ -624,7 +599,7 @@ void MainServer::changeSampleMIMO(int deviceSetIndex, int selectedDeviceIndex)
{
qDebug("MainServer::changeSampleMIMO: non existent device replaced by Test MIMO");
int testMIMODeviceIndex = DeviceEnumerator::instance()->getTestMIMODeviceIndex();
const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getMIMOSamplingDevice(testMIMODeviceIndex);
samplingDevice = DeviceEnumerator::instance()->getMIMOSamplingDevice(testMIMODeviceIndex);
deviceSet->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence);
deviceSet->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems);
deviceSet->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex);
@ -679,7 +654,7 @@ void MainServer::deleteChannel(int deviceSetIndex, int channelIndex)
void MainServer::addFeatureSet()
{
m_mainCore->appendFeatureSet();
emit m_mainCore->featureSetAdded(m_mainCore->getFeatureeSets().size() - 1);
emit m_mainCore->featureSetAdded((int) (m_mainCore->getFeatureeSets().size() - 1));
}
void MainServer::removeFeatureSet(unsigned int featureSetIndex)