diff --git a/Readme.md b/Readme.md index f2e7e7366..a6ddeed90 100644 --- a/Readme.md +++ b/Readme.md @@ -193,6 +193,7 @@ See the v1.0.1 first official relase [release notes](https://github.com/f4exb/sd

To Do

+ - UDP source plugin: add the possibility to launch an external command that will process the samples like a GNUradio headless flowgraph - Allow the handling of more than one device at the same time. For Rx/Tx devices like the BladeRF Rx and Tx appear as two logical devices with two plugin instances and a common handler for the physical device services both plugins. This effectively opens Tx support. - Tx channels - Possibility to connect channels for example Rx to Tx or single Rx channel to dual Rx channel supporting MI(MO) features like 360 degree polarization detection. @@ -202,7 +203,7 @@ See the v1.0.1 first official relase [release notes](https://github.com/f4exb/sd - Headless mode based on a saved configuration in above human readable form - Allow arbitrary sample rate for channelizers and demodulators (not multiple of 48 kHz). Prerequisite for polyphase channelizer - Implement polyphase channelizer - - Level calibration + - Level calibration - Even more demods ...

Developper's notes

diff --git a/plugins/channel/udpsrc/udpsrcgui.cpp b/plugins/channel/udpsrc/udpsrcgui.cpp index 8d873d263..f7418ad2c 100644 --- a/plugins/channel/udpsrc/udpsrcgui.cpp +++ b/plugins/channel/udpsrc/udpsrcgui.cpp @@ -305,7 +305,7 @@ void UDPSrcGUI::applySettings() int udpPort = ui->udpPort->text().toInt(&ok); - if((!ok) || (udpPort < 1) || (udpPort > 65535)) + if((!ok) || (udpPort < 1024) || (udpPort > 65535)) { udpPort = 9999; } diff --git a/plugins/samplesource/sdrdaemon/sdrdaemongui.cpp b/plugins/samplesource/sdrdaemon/sdrdaemongui.cpp index b8dd917e3..9c7205bc4 100644 --- a/plugins/samplesource/sdrdaemon/sdrdaemongui.cpp +++ b/plugins/samplesource/sdrdaemon/sdrdaemongui.cpp @@ -20,11 +20,13 @@ #include #include #include +#include #include "ui_sdrdaemongui.h" #include "plugin/pluginapi.h" #include "gui/colormapper.h" #include "dsp/dspengine.h" #include "mainwindow.h" +#include "util/simpleserializer.h" #include "sdrdaemongui.h" @@ -32,10 +34,8 @@ SDRdaemonGui::SDRdaemonGui(PluginAPI* pluginAPI, QWidget* parent) : QWidget(parent), ui(new Ui::SDRdaemonGui), m_pluginAPI(pluginAPI), - m_settings(), m_sampleSource(NULL), m_acquisition(false), - m_fileName("..."), m_sampleRate(0), m_centerFrequency(0), m_startingTimeStamp(0), @@ -45,14 +45,14 @@ SDRdaemonGui::SDRdaemonGui(PluginAPI* pluginAPI, QWidget* parent) : ui->setupUi(this); ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::ReverseGold)); ui->centerFrequency->setValueRange(7, 0, pow(10,7)); - ui->fileNameText->setText(m_fileName); connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware())); connect(&(m_pluginAPI->getMainWindow()->getMasterTimer()), SIGNAL(timeout()), this, SLOT(tick())); - displaySettings(); m_sampleSource = new SDRdaemonInput(m_pluginAPI->getMainWindow()->getMasterTimer()); connect(m_sampleSource->getOutputMessageQueueToGUI(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages())); DSPEngine::instance()->setSource(m_sampleSource); + + displaySettings(); } SDRdaemonGui::~SDRdaemonGui() @@ -77,11 +77,54 @@ QString SDRdaemonGui::getName() const void SDRdaemonGui::resetToDefaults() { - m_settings.resetToDefaults(); displaySettings(); - sendSettings(); } +QByteArray SDRdaemonGui::serialize() const +{ + bool ok; + SimpleSerializer s(1); + s.writeString(1, ui->address->text()); + uint32_t uintval = ui->port->text().toInt(&ok); + if((!ok) || (uintval < 1024) || (uintval > 65535)) { + uintval = 9090; + } + s.writeU32(2, uintval); + return s.final(); +} + +bool SDRdaemonGui::deserialize(const QByteArray& data) +{ + SimpleDeserializer d(data); + QString address; + uint32_t uintval; + quint16 port; + + if(!d.isValid()) { + resetToDefaults(); + return false; + } + + if(d.getVersion() == 1) { + uint32_t uintval; + d.readString(1, &address, "127.0.0.1"); + d.readU32(2, &uintval, 9090); + if ((uintval > 1024) && (uintval < 65536)) { + port = uintval; + } else { + port = 9090; + } + return true; + } else { + resetToDefaults(); + return false; + } + + ui->address->setText(address); + ui->port->setText(QString::number(port)); +} + + qint64 SDRdaemonGui::getCenterFrequency() const { return m_centerFrequency; @@ -91,24 +134,6 @@ void SDRdaemonGui::setCenterFrequency(qint64 centerFrequency) { m_centerFrequency = centerFrequency; displaySettings(); - sendSettings(); -} - -QByteArray SDRdaemonGui::serialize() const -{ - return m_settings.serialize(); -} - -bool SDRdaemonGui::deserialize(const QByteArray& data) -{ - if(m_settings.deserialize(data)) { - displaySettings(); - sendSettings(); - return true; - } else { - resetToDefaults(); - return false; - } } bool SDRdaemonGui::handleMessage(const Message& message) @@ -158,45 +183,37 @@ void SDRdaemonGui::displaySettings() { } -void SDRdaemonGui::sendSettings() -{ -} - -void SDRdaemonGui::updateHardware() -{ -} - void SDRdaemonGui::on_play_toggled(bool checked) { SDRdaemonInput::MsgConfigureSDRdaemonWork* message = SDRdaemonInput::MsgConfigureSDRdaemonWork::create(checked); m_sampleSource->getInputMessageQueue()->push(message); } -void SDRdaemonGui::on_showFileDialog_clicked(bool checked) +void SDRdaemonGui::on_applyButton_clicked(bool checked) { - QString fileName = QFileDialog::getOpenFileName(this, - tr("Open I/Q record file"), ".", tr("SDR I/Q Files (*.sdriq)")); - - if (fileName != "") - { - m_fileName = fileName; - ui->fileNameText->setText(m_fileName); - configureFileName(); - } + configureUDPLink(); } -void SDRdaemonGui::configureFileName() +void SDRdaemonGui::configureUDPLink() { - qDebug() << "SDRdaemonGui::configureFileName: " << m_fileName.toStdString().c_str(); - SDRdaemonInput::MsgConfigureSDRdaemonName* message = SDRdaemonInput::MsgConfigureSDRdaemonName::create(m_fileName); + bool ok; + QString udpAddress = ui->address->text(); + int udpPort = ui->port->text().toInt(&ok); + + if((!ok) || (udpPort < 1024) || (udpPort > 65535)) + { + udpPort = 9090; + } + + qDebug() << "SDRdaemonGui::configureUDPLink: " << udpAddress.toStdString().c_str() + << " : " << udpPort; + + SDRdaemonInput::MsgConfigureSDRdaemonUDPLink* message = SDRdaemonInput::MsgConfigureSDRdaemonUDPLink::create(udpAddress, udpPort); m_sampleSource->getInputMessageQueue()->push(message); } void SDRdaemonGui::updateWithAcquisition() { - ui->play->setEnabled(m_acquisition); - ui->play->setChecked(m_acquisition); - ui->showFileDialog->setEnabled(!m_acquisition); } void SDRdaemonGui::updateWithStreamData() @@ -204,7 +221,6 @@ void SDRdaemonGui::updateWithStreamData() ui->centerFrequency->setValue(m_centerFrequency/1000); QString s = QString::number(m_sampleRate/1000.0, 'f', 0); ui->sampleRateText->setText(tr("%1k").arg(s)); - ui->play->setEnabled(m_acquisition); updateWithStreamTime(); // TODO: remove when time data is implemented } @@ -222,7 +238,6 @@ void SDRdaemonGui::updateWithStreamTime() t = t.addSecs(t_sec); t = t.addMSecs(t_msec); QString s_time = t.toString("hh:mm:ss.zzz"); - ui->relTimeText->setText(s_time); quint64 startingTimeStampMsec = m_startingTimeStamp * 1000; QDateTime dt = QDateTime::fromMSecsSinceEpoch(startingTimeStampMsec); diff --git a/plugins/samplesource/sdrdaemon/sdrdaemongui.h b/plugins/samplesource/sdrdaemon/sdrdaemongui.h index b9216f9b0..d192453f7 100644 --- a/plugins/samplesource/sdrdaemon/sdrdaemongui.h +++ b/plugins/samplesource/sdrdaemon/sdrdaemongui.h @@ -40,22 +40,19 @@ public: QString getName() const; void resetToDefaults(); - virtual qint64 getCenterFrequency() const; - virtual void setCenterFrequency(qint64 centerFrequency); QByteArray serialize() const; bool deserialize(const QByteArray& data); + virtual qint64 getCenterFrequency() const; + virtual void setCenterFrequency(qint64 centerFrequency); virtual bool handleMessage(const Message& message); private: Ui::SDRdaemonGui* ui; PluginAPI* m_pluginAPI; - SDRdaemonInput::Settings m_settings; QTimer m_updateTimer; - std::vector m_gains; SampleSource* m_sampleSource; bool m_acquisition; - QString m_fileName; int m_sampleRate; quint64 m_centerFrequency; std::time_t m_startingTimeStamp; @@ -64,9 +61,7 @@ private: void displaySettings(); void displayTime(); - void sendSettings(); - void updateHardware(); - void configureFileName(); + void configureUDPLink(); void updateWithAcquisition(); void updateWithStreamData(); void updateWithStreamTime(); @@ -75,7 +70,7 @@ private slots: void handleSourceMessages(); void on_playLoop_toggled(bool checked); void on_play_toggled(bool checked); - void on_showFileDialog_clicked(bool checked); + void on_applyButton_clicked(bool checked); void tick(); }; diff --git a/plugins/samplesource/sdrdaemon/sdrdaemongui.ui b/plugins/samplesource/sdrdaemon/sdrdaemongui.ui index 228619b6a..c6e778eeb 100644 --- a/plugins/samplesource/sdrdaemon/sdrdaemongui.ui +++ b/plugins/samplesource/sdrdaemon/sdrdaemongui.ui @@ -147,7 +147,7 @@ - + 30 @@ -235,108 +235,6 @@ - - - - - - Dec. - - - - - - - Decimation factor - - - 6 - - - 1 - - - 0 - - - Qt::Horizontal - - - - - - - 1 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 50 - 0 - - - - 0k - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - 24 - 24 - - - - - 24 - 24 - - - - Open file - - - - - - - :/preset-load.png:/preset-load.png - - - - - - - false - - - File currently opened - - - ... - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - @@ -345,104 +243,7 @@ - - - Qt::Horizontal - - - - - - - - - Play in a loop - - - - - - - :/playloop.png:/playloop.png - - - - 16 - 16 - - - - true - - - - - - - Stopped / Play / Pause - - - - - - - :/play.png - :/pause.png - :/stop.png - :/stop.png - :/play.png - :/pause.png - :/play.png - :/pause.png:/play.png - - - - 16 - 16 - - - - true - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - - - - false - - - Record time from start - - - 00:00:00.000 - - - - + @@ -453,11 +254,6 @@
gui/valuedial.h
1 - - ButtonSwitch - QToolButton -
gui/buttonswitch.h
-
diff --git a/plugins/samplesource/sdrdaemon/sdrdaemoninput.cpp b/plugins/samplesource/sdrdaemon/sdrdaemoninput.cpp index 55e3b998d..f5005be78 100644 --- a/plugins/samplesource/sdrdaemon/sdrdaemoninput.cpp +++ b/plugins/samplesource/sdrdaemon/sdrdaemoninput.cpp @@ -27,55 +27,18 @@ #include "sdrdaemoninput.h" #include "sdrdaemonthread.h" -MESSAGE_CLASS_DEFINITION(SDRdaemonInput::MsgConfigureSDRdaemon, Message) -MESSAGE_CLASS_DEFINITION(SDRdaemonInput::MsgConfigureSDRdaemonName, Message) +MESSAGE_CLASS_DEFINITION(SDRdaemonInput::MsgConfigureSDRdaemonUDPLink, Message) MESSAGE_CLASS_DEFINITION(SDRdaemonInput::MsgConfigureSDRdaemonWork, Message) MESSAGE_CLASS_DEFINITION(SDRdaemonInput::MsgConfigureSDRdaemonStreamTiming, Message) MESSAGE_CLASS_DEFINITION(SDRdaemonInput::MsgReportSDRdaemonAcquisition, Message) MESSAGE_CLASS_DEFINITION(SDRdaemonInput::MsgReportSDRdaemonStreamData, Message) MESSAGE_CLASS_DEFINITION(SDRdaemonInput::MsgReportSDRdaemonStreamTiming, Message) -SDRdaemonInput::Settings::Settings() : - m_fileName("./test.sdriq") -{ -} - -void SDRdaemonInput::Settings::resetToDefaults() -{ - m_fileName = "./test.sdriq"; -} - -QByteArray SDRdaemonInput::Settings::serialize() const -{ - SimpleSerializer s(1); - s.writeString(1, m_fileName); - return s.final(); -} - -bool SDRdaemonInput::Settings::deserialize(const QByteArray& data) -{ - SimpleDeserializer d(data); - - if(!d.isValid()) { - resetToDefaults(); - return false; - } - - if(d.getVersion() == 1) { - int intval; - d.readString(1, &m_fileName, "./test.sdriq"); - return true; - } else { - resetToDefaults(); - return false; - } -} - SDRdaemonInput::SDRdaemonInput(const QTimer& masterTimer) : - m_settings(), + m_address("127.0.0.1"), + m_port(9090), m_SDRdaemonThread(NULL), m_deviceDescription(), - m_fileName("..."), m_sampleRate(0), m_centerFrequency(0), m_startingTimeStamp(0), @@ -164,10 +127,10 @@ std::time_t SDRdaemonInput::getStartingTimeStamp() const bool SDRdaemonInput::handleMessage(const Message& message) { - if (MsgConfigureSDRdaemonName::match(message)) + if (MsgConfigureSDRdaemonUDPLink::match(message)) { - MsgConfigureSDRdaemonName& conf = (MsgConfigureSDRdaemonName&) message; - m_fileName = conf.getFileName(); + MsgConfigureSDRdaemonUDPLink& conf = (MsgConfigureSDRdaemonUDPLink&) message; + updateLink(conf.getAddress(), conf.getPort()); return true; } else if (MsgConfigureSDRdaemonWork::match(message)) @@ -210,14 +173,50 @@ bool SDRdaemonInput::handleMessage(const Message& message) } } -bool SDRdaemonInput::applySettings(const Settings& settings, bool force) +void SDRdaemonInput::updateLink(const QString& address, quint16 port) { QMutexLocker mutexLocker(&m_mutex); bool wasRunning = false; - if((m_settings.m_fileName != settings.m_fileName) || force) + if ((m_address != address) || (m_port != port)) { - m_settings.m_fileName = settings.m_fileName; + if (m_SDRdaemonThread != 0) + { + wasRunning = m_SDRdaemonThread->isRunning(); + + if (wasRunning) + { + m_SDRdaemonThread->stopWork(); + } + } + + if (m_SDRdaemonThread != 0) + { + m_SDRdaemonThread->updateLink(address, port); + + if (wasRunning) + { + m_SDRdaemonThread->startWork(); + } + } + + m_address = address; + m_port = port; + + qDebug() << "SDRdaemonInput::updateLink:" + << " address: " << m_address.toStdString().c_str() + << "port: " << m_port; + } +} + +void SDRdaemonInput:: updateSampleRate(int sampleRate) +{ + QMutexLocker mutexLocker(&m_mutex); + bool wasRunning = false; + + if (m_sampleRate != sampleRate) + { + m_sampleRate = sampleRate; if (m_SDRdaemonThread != 0) { @@ -242,11 +241,7 @@ bool SDRdaemonInput::applySettings(const Settings& settings, bool force) DSPSignalNotification *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency); DSPEngine::instance()->getInputMessageQueue()->push(notif); - qDebug() << "SDRdaemonInput::applySettings:" - << " center freq: " << m_centerFrequency << " Hz" - << " sample rate: " << m_sampleRate - << " Unix timestamp: " << m_startingTimeStamp; + qDebug() << "SDRdaemonInput::updateSampleRate:" + << " sample rate: " << m_sampleRate; } - - return true; } diff --git a/plugins/samplesource/sdrdaemon/sdrdaemoninput.h b/plugins/samplesource/sdrdaemon/sdrdaemoninput.h index 01e004b6c..46d0fef0b 100644 --- a/plugins/samplesource/sdrdaemon/sdrdaemoninput.h +++ b/plugins/samplesource/sdrdaemon/sdrdaemoninput.h @@ -27,52 +27,26 @@ class SDRdaemonThread; class SDRdaemonInput : public SampleSource { public: - struct Settings { - QString m_fileName; - - Settings(); - void resetToDefaults(); - QByteArray serialize() const; - bool deserialize(const QByteArray& data); - }; - - class MsgConfigureSDRdaemon : public Message { + class MsgConfigureSDRdaemonUDPLink : public Message { MESSAGE_CLASS_DECLARATION public: - const Settings& getSettings() const { return m_settings; } + const QString& getAddress() const { return m_address; } + quint16 getPort() const { return m_port; } - static MsgConfigureSDRdaemon* create(const Settings& settings) + static MsgConfigureSDRdaemonUDPLink* create(const QString& address, quint16 port) { - return new MsgConfigureSDRdaemon(settings); + return new MsgConfigureSDRdaemonUDPLink(address, port); } private: - Settings m_settings; + QString m_address; + quint16 m_port; - MsgConfigureSDRdaemon(const Settings& settings) : + MsgConfigureSDRdaemonUDPLink(const QString& address, quint16 port) : Message(), - m_settings(settings) - { } - }; - - class MsgConfigureSDRdaemonName : public Message { - MESSAGE_CLASS_DECLARATION - - public: - const QString& getFileName() const { return m_fileName; } - - static MsgConfigureSDRdaemonName* create(const QString& fileName) - { - return new MsgConfigureSDRdaemonName(fileName); - } - - private: - QString m_fileName; - - MsgConfigureSDRdaemonName(const QString& fileName) : - Message(), - m_fileName(fileName) + m_address(address), + m_port(port) { } }; @@ -195,16 +169,17 @@ public: private: QMutex m_mutex; - Settings m_settings; + QString m_address; + quint16 m_port; SDRdaemonThread* m_SDRdaemonThread; QString m_deviceDescription; - QString m_fileName; int m_sampleRate; quint64 m_centerFrequency; std::time_t m_startingTimeStamp; const QTimer& m_masterTimer; - bool applySettings(const Settings& settings, bool force); + void updateLink(const QString& address, quint16 port); + void updateSampleRate(int sampleRate); }; #endif // INCLUDE_SDRDAEMONINPUT_H diff --git a/plugins/samplesource/sdrdaemon/sdrdaemonthread.h b/plugins/samplesource/sdrdaemon/sdrdaemonthread.h index 373348598..046d108e7 100644 --- a/plugins/samplesource/sdrdaemon/sdrdaemonthread.h +++ b/plugins/samplesource/sdrdaemon/sdrdaemonthread.h @@ -43,6 +43,7 @@ public: void startWork(); void stopWork(); void setSamplerate(uint32_t samplerate); + void updateLink(const QString& address, quint16 port); bool isRunning() const { return m_running; } std::size_t getSamplesCount() const { return m_samplesCount; }