diff --git a/plugins/channelrx/udpsrc/udpsrcgui.cpp b/plugins/channelrx/udpsrc/udpsrcgui.cpp index 04a835cb9..781b699e8 100644 --- a/plugins/channelrx/udpsrc/udpsrcgui.cpp +++ b/plugins/channelrx/udpsrc/udpsrcgui.cpp @@ -15,11 +15,11 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include "../../channelrx/udpsrc/udpsrcgui.h" +#include "udpsrcgui.h" -#include -#include -#include "../../../sdrbase/dsp/threadedbasebandsamplesink.h" +#include "device/devicesourceapi.h" +#include "dsp/downchannelizer.h" +#include "dsp/threadedbasebandsamplesink.h" #include "plugin/pluginapi.h" #include "dsp/spectrumvis.h" #include "dsp/dspengine.h" diff --git a/plugins/channelrx/udpsrc/udpsrcgui.h b/plugins/channelrx/udpsrc/udpsrcgui.h index 44a179c88..cd3978cb1 100644 --- a/plugins/channelrx/udpsrc/udpsrcgui.h +++ b/plugins/channelrx/udpsrc/udpsrcgui.h @@ -24,7 +24,7 @@ #include "dsp/channelmarker.h" #include "dsp/movingaverage.h" -#include "../../channelrx/udpsrc/udpsrc.h" +#include "udpsrc.h" class PluginAPI; class DeviceSourceAPI; diff --git a/plugins/channeltx/CMakeLists.txt b/plugins/channeltx/CMakeLists.txt index 764c280fd..30118e09e 100644 --- a/plugins/channeltx/CMakeLists.txt +++ b/plugins/channeltx/CMakeLists.txt @@ -6,6 +6,7 @@ add_subdirectory(modam) add_subdirectory(modnfm) add_subdirectory(modssb) add_subdirectory(modwfm) +add_subdirectory(udpsink) if (OpenCV_FOUND) add_subdirectory(modatv) diff --git a/plugins/channeltx/udpsink/CMakeLists.txt b/plugins/channeltx/udpsink/CMakeLists.txt new file mode 100644 index 000000000..e61c73f0f --- /dev/null +++ b/plugins/channeltx/udpsink/CMakeLists.txt @@ -0,0 +1,44 @@ +project(udpsink) + +set(udpsink_SOURCES + udpsink.cpp + udpsinkgui.cpp + udpsinkplugin.cpp +) + +set(udpsink_HEADERS + udpsink.h + udpsinkgui.h + udpsinkplugin.h +) + +set(udpsink_FORMS + udpsinkgui.ui +) + +include_directories( + . + ${CMAKE_CURRENT_BINARY_DIR} +) + +#include(${QT_USE_FILE}) +add_definitions(${QT_DEFINITIONS}) +add_definitions(-DQT_PLUGIN) +add_definitions(-DQT_SHARED) + +qt5_wrap_ui(udpsink_FORMS_HEADERS ${udpsink_FORMS}) + +add_library(modudpsink SHARED + ${udpsink_SOURCES} + ${udpsink_HEADERS_MOC} + ${udpsink_FORMS_HEADERS} +) + +target_link_libraries(modudpsink + ${QT_LIBRARIES} + sdrbase +) + +qt5_use_modules(modudpsink Core Widgets Network) + +install(TARGETS modudpsink DESTINATION lib/plugins/channeltx) diff --git a/plugins/channeltx/udpsink/udpsink.cpp b/plugins/channeltx/udpsink/udpsink.cpp new file mode 100644 index 000000000..d42f01e20 --- /dev/null +++ b/plugins/channeltx/udpsink/udpsink.cpp @@ -0,0 +1,112 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include + +#include "dsp/upchannelizer.h" +#include "udpsink.h" + +MESSAGE_CLASS_DEFINITION(UDPSink::MsgUDPSinkConfigure, Message) + +UDPSink::UDPSink(MessageQueue* uiMessageQueue, UDPSinkGUI* udpSinkGUI, BasebandSampleSink* spectrum) : + m_uiMessageQueue(uiMessageQueue), + m_udpSinkGUI(udpSinkGUI), + m_spectrum(spectrum), + m_settingsMutex(QMutex::Recursive) +{ +} + +UDPSink::~UDPSink() +{ +} + +void UDPSink::start() +{ +} + +void UDPSink::stop() +{ +} + +void UDPSink::pull(Sample& sample) +{ + sample.m_real = 0.0f; + sample.m_imag = 0.0f; +} + +bool UDPSink::handleMessage(const Message& cmd) +{ + qDebug() << "UDPSink::handleMessage"; + + if (UpChannelizer::MsgChannelizerNotification::match(cmd)) + { + UpChannelizer::MsgChannelizerNotification& notif = (UpChannelizer::MsgChannelizerNotification&) cmd; + + m_settingsMutex.lock(); + + m_config.m_basebandSampleRate = notif.getBasebandSampleRate(); + m_config.m_outputSampleRate = notif.getSampleRate(); + m_config.m_inputFrequencyOffset = notif.getFrequencyOffset(); + + m_settingsMutex.unlock(); + + qDebug() << "UDPSink::handleMessage: MsgChannelizerNotification:" + << " m_basebandSampleRate: " << m_config.m_basebandSampleRate + << " m_outputSampleRate: " << m_config.m_outputSampleRate + << " m_inputFrequencyOffset: " << m_config.m_inputFrequencyOffset; + + return true; + } + else if (MsgUDPSinkConfigure::match(cmd)) + { + MsgUDPSinkConfigure& cfg = (MsgUDPSinkConfigure&) cmd; + + m_settingsMutex.lock(); + + m_config.m_sampleFormat = cfg.getSampleFormat(); + m_config.m_inputSampleRate = cfg.getInputSampleRate(); + m_config.m_rfBandwidth = cfg.getRFBandwidth(); + m_config.m_fmDeviation = cfg.getFMDeviation(); + m_config.m_udpAddressStr = cfg.getUDPAddress(); + m_config.m_udpPort = cfg.getUDPPort(); + + m_settingsMutex.unlock(); + + return true; + } + else + { + return false; + } +} + +void UDPSink::configure(MessageQueue* messageQueue, + SampleFormat sampleFormat, + Real outputSampleRate, + Real rfBandwidth, + int fmDeviation, + QString& udpAddress, + int udpPort) +{ + Message* cmd = MsgUDPSinkConfigure::create(sampleFormat, + outputSampleRate, + rfBandwidth, + fmDeviation, + udpAddress, + udpPort); + messageQueue->push(cmd); +} + diff --git a/plugins/channeltx/udpsink/udpsink.h b/plugins/channeltx/udpsink/udpsink.h new file mode 100644 index 000000000..775fab659 --- /dev/null +++ b/plugins/channeltx/udpsink/udpsink.h @@ -0,0 +1,150 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef PLUGINS_CHANNELTX_UDPSINK_UDPSINK_H_ +#define PLUGINS_CHANNELTX_UDPSINK_UDPSINK_H_ + +#include + +#include "dsp/basebandsamplesource.h" +#include "dsp/basebandsamplesink.h" +#include "util/message.h" + +class UDPSinkGUI; + +class UDPSink : public BasebandSampleSource { + Q_OBJECT + +public: + enum SampleFormat { + FormatS16LE, + FormatNFM, + FormatNFMMono, + FormatLSB, + FormatUSB, + FormatLSBMono, + FormatUSBMono, + FormatAMMono, + FormatNone + }; + + UDPSink(MessageQueue* uiMessageQueue, UDPSinkGUI* udpSinkGUI, BasebandSampleSink* spectrum); + virtual ~UDPSink(); + + virtual void start(); + virtual void stop(); + virtual void pull(Sample& sample); + virtual bool handleMessage(const Message& cmd); + + void configure(MessageQueue* messageQueue, + SampleFormat sampleFormat, + Real inputSampleRate, + Real rfBandwidth, + int fmDeviation, + QString& udpAddress, + int udpPort); + +private: + class MsgUDPSinkConfigure : public Message { + MESSAGE_CLASS_DECLARATION + + public: + SampleFormat getSampleFormat() const { return m_sampleFormat; } + Real getInputSampleRate() const { return m_inputSampleRate; } + Real getRFBandwidth() const { return m_rfBandwidth; } + int getFMDeviation() const { return m_fmDeviation; } + const QString& getUDPAddress() const { return m_udpAddress; } + int getUDPPort() const { return m_udpPort; } + + static MsgUDPSinkConfigure* create(SampleFormat + sampleFormat, + Real inputSampleRate, + Real rfBandwidth, + int fmDeviation, + QString& udpAddress, + int udpPort) + { + return new MsgUDPSinkConfigure(sampleFormat, + inputSampleRate, + rfBandwidth, + fmDeviation, + udpAddress, + udpPort); + } + + private: + SampleFormat m_sampleFormat; + Real m_inputSampleRate; + Real m_rfBandwidth; + int m_fmDeviation; + QString m_udpAddress; + int m_udpPort; + + MsgUDPSinkConfigure(SampleFormat sampleFormat, + Real inputSampleRate, + Real rfBandwidth, + int fmDeviation, + QString& udpAddress, + int udpPort) : + Message(), + m_sampleFormat(sampleFormat), + m_inputSampleRate(inputSampleRate), + m_rfBandwidth(rfBandwidth), + m_fmDeviation(fmDeviation), + m_udpAddress(udpAddress), + m_udpPort(udpPort) + { } + }; + + struct Config { + int m_basebandSampleRate; + Real m_outputSampleRate; + int m_sampleFormat; + Real m_inputSampleRate; + qint64 m_inputFrequencyOffset; + Real m_rfBandwidth; + int m_fmDeviation; + + QString m_udpAddressStr; + quint16 m_udpPort; + + Config() : + m_basebandSampleRate(0), + m_outputSampleRate(0), + m_sampleFormat(0), + m_inputSampleRate(0), + m_inputFrequencyOffset(0), + m_rfBandwidth(0), + m_fmDeviation(0), + m_udpAddressStr("127.0.0.1"), + m_udpPort(9999) + {} + }; + + Config m_config; + Config m_running; + + MessageQueue* m_uiMessageQueue; + UDPSinkGUI* m_udpSinkGUI; + BasebandSampleSink* m_spectrum; + + QMutex m_settingsMutex; +}; + + + + +#endif /* PLUGINS_CHANNELTX_UDPSINK_UDPSINK_H_ */ diff --git a/plugins/channeltx/udpsink/udpsinkgui.cpp b/plugins/channeltx/udpsink/udpsinkgui.cpp new file mode 100644 index 000000000..762e42ae0 --- /dev/null +++ b/plugins/channeltx/udpsink/udpsinkgui.cpp @@ -0,0 +1,375 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "device/devicesinkapi.h" +#include "dsp/upchannelizer.h" +#include "dsp/threadedbasebandsamplesource.h" +#include "dsp/spectrumvis.h" +#include "plugin/pluginapi.h" +#include "util/simpleserializer.h" +#include "dsp/dspengine.h" +#include "mainwindow.h" + +#include "udpsinkgui.h" +#include "ui_udpsinkgui.h" + +const QString UDPSinkGUI::m_channelID = "sdrangel.channeltx.udpsink"; + +UDPSinkGUI* UDPSinkGUI::create(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI) +{ + UDPSinkGUI* gui = new UDPSinkGUI(pluginAPI, deviceAPI); + return gui; +} + +void UDPSinkGUI::destroy() +{ +} + +void UDPSinkGUI::setName(const QString& name) +{ + setObjectName(name); +} + +QString UDPSinkGUI::getName() const +{ + return objectName(); +} + +qint64 UDPSinkGUI::getCenterFrequency() const { + return m_channelMarker.getCenterFrequency(); +} + +void UDPSinkGUI::setCenterFrequency(qint64 centerFrequency) +{ + m_channelMarker.setCenterFrequency(centerFrequency); + applySettings(); +} + +void UDPSinkGUI::resetToDefaults() +{ + blockApplySettings(true); + + ui->sampleFormat->setCurrentIndex(0); + ui->sampleRate->setText("48000"); + ui->rfBandwidth->setText("32000"); + ui->fmDeviation->setText("2500"); + ui->udpAddress->setText("127.0.0.1"); + ui->udpPort->setText("9999"); + ui->spectrumGUI->resetToDefaults(); + ui->volume->setValue(20); + + blockApplySettings(false); + applySettings(); +} + +QByteArray UDPSinkGUI::serialize() const +{ + SimpleSerializer s(1); + s.writeBlob(1, saveState()); + s.writeS32(2, m_channelMarker.getCenterFrequency()); + s.writeS32(3, m_sampleFormat); + s.writeReal(4, m_inputSampleRate); + s.writeReal(5, m_rfBandwidth); + s.writeS32(6, m_udpPort); + s.writeBlob(7, ui->spectrumGUI->serialize()); + s.writeS32(8, m_channelMarker.getCenterFrequency()); + s.writeString(9, m_udpAddress); + s.writeS32(10, (qint32)m_volume); + s.writeS32(11, m_fmDeviation); + return s.final(); +} + +bool UDPSinkGUI::deserialize(const QByteArray& data) +{ + SimpleDeserializer d(data); + + if (!d.isValid()) + { + resetToDefaults(); + return false; + } + + if (d.getVersion() == 1) + { + QByteArray bytetmp; + QString strtmp; + qint32 s32tmp; + Real realtmp; + + blockApplySettings(true); + m_channelMarker.blockSignals(true); + + d.readBlob(1, &bytetmp); + restoreState(bytetmp); + d.readS32(2, &s32tmp, 0); + m_channelMarker.setCenterFrequency(s32tmp); + d.readS32(3, &s32tmp, UDPSink::FormatS16LE); + switch(s32tmp) { + case UDPSink::FormatS16LE: + ui->sampleFormat->setCurrentIndex(0); + break; + case UDPSink::FormatNFM: + ui->sampleFormat->setCurrentIndex(1); + break; + case UDPSink::FormatNFMMono: + ui->sampleFormat->setCurrentIndex(2); + break; + case UDPSink::FormatLSB: + ui->sampleFormat->setCurrentIndex(3); + break; + case UDPSink::FormatUSB: + ui->sampleFormat->setCurrentIndex(4); + break; + case UDPSink::FormatLSBMono: + ui->sampleFormat->setCurrentIndex(5); + break; + case UDPSink::FormatUSBMono: + ui->sampleFormat->setCurrentIndex(6); + break; + case UDPSink::FormatAMMono: + ui->sampleFormat->setCurrentIndex(7); + break; + default: + ui->sampleFormat->setCurrentIndex(0); + break; + } + d.readReal(4, &realtmp, 48000); + ui->sampleRate->setText(QString("%1").arg(realtmp, 0)); + d.readReal(5, &realtmp, 32000); + ui->rfBandwidth->setText(QString("%1").arg(realtmp, 0)); + d.readS32(6, &s32tmp, 9999); + ui->udpPort->setText(QString("%1").arg(s32tmp)); + d.readBlob(7, &bytetmp); + ui->spectrumGUI->deserialize(bytetmp); + d.readS32(8, &s32tmp, 0); + m_channelMarker.setCenterFrequency(s32tmp); + d.readString(9, &strtmp, "127.0.0.1"); + ui->udpAddress->setText(strtmp); + d.readS32(10, &s32tmp, 20); + ui->volume->setValue(s32tmp); + d.readS32(11, &s32tmp, 2500); + ui->fmDeviation->setText(QString("%1").arg(s32tmp)); + + blockApplySettings(false); + m_channelMarker.blockSignals(false); + + applySettings(); + return true; + } + else + { + resetToDefaults(); + return false; + } +} + +bool UDPSinkGUI::handleMessage(const Message& message __attribute__((unused))) +{ + qDebug() << "UDPSinkGUI::handleMessage"; + return false; +} + +void UDPSinkGUI::handleSourceMessages() +{ + Message* message; + + while ((message = m_udpSink->getOutputMessageQueue()->pop()) != 0) + { + if (handleMessage(*message)) + { + delete message; + } + } +} + +UDPSinkGUI::UDPSinkGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* parent) : + RollupWidget(parent), + ui(new Ui::UDPSinkGUI), + m_pluginAPI(pluginAPI), + m_deviceAPI(deviceAPI), + m_channelMarker(this), + m_doApplySettings(true) +{ + ui->setupUi(this); + connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); + connect(this, SIGNAL(menuDoubleClickEvent()), this, SLOT(onMenuDoubleClicked())); + setAttribute(Qt::WA_DeleteOnClose, true); + + m_spectrumVis = new SpectrumVis(ui->glSpectrum); + m_udpSink = new UDPSink(m_pluginAPI->getMainWindowMessageQueue(), this, m_spectrumVis); + m_channelizer = new UpChannelizer(m_udpSink); + m_threadedChannelizer = new ThreadedBasebandSampleSource(m_channelizer, this); + m_deviceAPI->addThreadedSource(m_threadedChannelizer); + + ui->fmDeviation->setEnabled(false); + ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03))); + ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold)); + ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999); + + ui->glSpectrum->setCenterFrequency(0); + ui->glSpectrum->setSampleRate(ui->sampleRate->text().toInt()); + ui->glSpectrum->setDisplayWaterfall(true); + ui->glSpectrum->setDisplayMaxHold(true); + m_spectrumVis->configure(m_spectrumVis->getInputMessageQueue(), 64, 10, FFTWindow::BlackmanHarris); + + ui->glSpectrum->connectTimer(m_pluginAPI->getMainWindow()->getMasterTimer()); + connect(&m_pluginAPI->getMainWindow()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); + + //m_channelMarker = new ChannelMarker(this); + m_channelMarker.setBandwidth(16000); + m_channelMarker.setCenterFrequency(0); + m_channelMarker.setColor(Qt::green); + m_channelMarker.setVisible(true); + + connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged())); + + m_deviceAPI->registerChannelInstance(m_channelID, this); + m_deviceAPI->addChannelMarker(&m_channelMarker); + m_deviceAPI->addRollupWidget(this); + + applySettings(); + + connect(m_udpSink->getOutputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages())); +} + +UDPSinkGUI::~UDPSinkGUI() +{ + m_deviceAPI->removeChannelInstance(this); + m_deviceAPI->removeThreadedSource(m_threadedChannelizer); + delete m_threadedChannelizer; + delete m_channelizer; + delete m_udpSink; + delete m_spectrumVis; + delete ui; +} + +void UDPSinkGUI::blockApplySettings(bool block) +{ + m_doApplySettings = !block; +} + +void UDPSinkGUI::applySettings() +{ + if (m_doApplySettings) + { + bool ok; + + Real inputSampleRate = ui->sampleRate->text().toDouble(&ok); + + if((!ok) || (inputSampleRate < 1000)) + { + inputSampleRate = 48000; + } + + Real rfBandwidth = ui->rfBandwidth->text().toDouble(&ok); + + if((!ok) || (rfBandwidth > inputSampleRate)) + { + rfBandwidth = inputSampleRate; + } + + m_udpAddress = ui->udpAddress->text(); + + int udpPort = ui->udpPort->text().toInt(&ok); + + if((!ok) || (udpPort < 1024) || (udpPort > 65535)) + { + udpPort = 9999; + } + + int fmDeviation = ui->fmDeviation->text().toInt(&ok); + + if ((!ok) || (fmDeviation < 1)) + { + fmDeviation = 2500; + } + + setTitleColor(m_channelMarker.getColor()); + ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency()); + ui->sampleRate->setText(QString("%1").arg(inputSampleRate, 0)); + ui->rfBandwidth->setText(QString("%1").arg(rfBandwidth, 0)); + //ui->udpAddress->setText(m_udpAddress); + ui->udpPort->setText(QString("%1").arg(udpPort)); + ui->fmDeviation->setText(QString("%1").arg(fmDeviation)); + m_channelMarker.disconnect(this, SLOT(channelMarkerChanged())); + m_channelMarker.setBandwidth((int)rfBandwidth); + connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged())); + ui->glSpectrum->setSampleRate(inputSampleRate); + + m_channelizer->configure(m_channelizer->getInputMessageQueue(), + inputSampleRate, + m_channelMarker.getCenterFrequency()); + + UDPSink::SampleFormat sampleFormat; + + switch(ui->sampleFormat->currentIndex()) + { + case 0: + sampleFormat = UDPSink::FormatS16LE; + ui->fmDeviation->setEnabled(false); + break; + case 1: + sampleFormat = UDPSink::FormatNFM; + ui->fmDeviation->setEnabled(true); + break; + case 2: + sampleFormat = UDPSink::FormatNFMMono; + ui->fmDeviation->setEnabled(true); + break; + case 3: + sampleFormat = UDPSink::FormatLSB; + ui->fmDeviation->setEnabled(false); + break; + case 4: + sampleFormat = UDPSink::FormatUSB; + ui->fmDeviation->setEnabled(false); + break; + case 5: + sampleFormat = UDPSink::FormatLSBMono; + ui->fmDeviation->setEnabled(false); + break; + case 6: + sampleFormat = UDPSink::FormatUSBMono; + ui->fmDeviation->setEnabled(false); + break; + case 7: + sampleFormat = UDPSink::FormatAMMono; + ui->fmDeviation->setEnabled(false); + break; + default: + sampleFormat = UDPSink::FormatS16LE; + ui->fmDeviation->setEnabled(false); + break; + } + + m_sampleFormat = sampleFormat; + m_inputSampleRate = inputSampleRate; + m_rfBandwidth = rfBandwidth; + m_fmDeviation = fmDeviation; + m_udpPort = udpPort; + + m_udpSink->configure(m_udpSink->getInputMessageQueue(), + sampleFormat, + inputSampleRate, + rfBandwidth, + fmDeviation, + m_udpAddress, + udpPort); + + ui->applyBtn->setEnabled(false); + } +} + diff --git a/plugins/channeltx/udpsink/udpsinkgui.h b/plugins/channeltx/udpsink/udpsinkgui.h new file mode 100644 index 000000000..dda6c194a --- /dev/null +++ b/plugins/channeltx/udpsink/udpsinkgui.h @@ -0,0 +1,87 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef PLUGINS_CHANNELTX_UDPSINK_UDPSINKGUI_H_ +#define PLUGINS_CHANNELTX_UDPSINK_UDPSINKGUI_H_ + +#include + +#include "gui/rollupwidget.h" +#include "plugin/plugingui.h" +#include "dsp/channelmarker.h" + +#include "udpsink.h" + +class PluginAPI; +class DeviceSinkAPI; +class ThreadedBasebandSampleSource; +class UpChannelizer; +class UDPSink; +class SpectrumVis; + +namespace Ui { + class UDPSinkGUI; +} + +class UDPSinkGUI : public RollupWidget, public PluginGUI { + Q_OBJECT + +public: + static UDPSinkGUI* create(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI); + void destroy(); + + void setName(const QString& name); + QString getName() const; + virtual qint64 getCenterFrequency() const; + virtual void setCenterFrequency(qint64 centerFrequency); + virtual void resetToDefaults(); + virtual QByteArray serialize() const; + virtual bool deserialize(const QByteArray& data); + virtual bool handleMessage(const Message& message); + + static const QString m_channelID; + +private slots: + void handleSourceMessages(); + +private: + Ui::UDPSinkGUI* ui; + PluginAPI* m_pluginAPI; + DeviceSinkAPI* m_deviceAPI; + ThreadedBasebandSampleSource* m_threadedChannelizer; + UpChannelizer* m_channelizer; + SpectrumVis* m_spectrumVis; + UDPSink* m_udpSink; + ChannelMarker m_channelMarker; + + // settings + UDPSink::SampleFormat m_sampleFormat; + Real m_inputSampleRate; + Real m_rfBandwidth; + int m_fmDeviation; + int m_volume; + QString m_udpAddress; + int m_udpPort; + bool m_doApplySettings; + + explicit UDPSinkGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* parent = NULL); + virtual ~UDPSinkGUI(); + + void blockApplySettings(bool block); + void applySettings(); +}; + +#endif /* PLUGINS_CHANNELTX_UDPSINK_UDPSINKGUI_H_ */ diff --git a/plugins/channeltx/udpsink/udpsinkgui.ui b/plugins/channeltx/udpsink/udpsinkgui.ui new file mode 100644 index 000000000..4b028368e --- /dev/null +++ b/plugins/channeltx/udpsink/udpsinkgui.ui @@ -0,0 +1,522 @@ + + + UDPSinkGUI + + + + 0 + 0 + 316 + 355 + + + + + 316 + 0 + + + + + 400 + 16777215 + + + + + Sans Serif + 9 + + + + UDP Sample Source + + + + + 2 + 2 + 312 + 142 + + + + + 312 + 0 + + + + Settings + + + + 2 + + + 2 + + + 2 + + + 2 + + + 3 + + + + + Format + + + + + + + Samples format + + + 0 + + + + S16LE I/Q + + + + + S16LE NFM + + + + + S16LE NFM Mono + + + + + S16LE LSB + + + + + S16LE USB + + + + + S16LE LSB Mono + + + + + S16LE USB Mono + + + + + S16LE AM Mono + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Channel power + + + Qt::LeftToRight + + + 0.0 + + + + + + + dB + + + + + + + + + Rate (Hz) + + + + + + + + + false + + + Apply text input and/or samples format + + + Apply + + + + + + + + + 2 + + + + + + 16 + 16777215 + + + + Df + + + + + + + + 0 + 0 + + + + + 32 + 16 + + + + + DejaVu Sans Mono + 12 + + + + PointingHandCursor + + + Qt::StrongFocus + + + Demod shift frequency from center in Hz + + + + + + + + + + + + 26 + 26 + 26 + + + + + + + 255 + 255 + 255 + + + + + + + + + 26 + 26 + 26 + + + + + + + 255 + 255 + 255 + + + + + + + + + 118 + 118 + 117 + + + + + + + 255 + 255 + 255 + + + + + + + + + 8 + + + + Hz + + + + + + + + + + + FMd (Hz) + + + + + + + FM deviation in Hz (for S16LE NFM format) + + + 2500 + + + + + + + + + RF BW (Hz) + + + + + + + Signal bandwidth + + + 32000 + + + + + + + + + Vol + + + + + + + Audio volume + + + 100 + + + 1 + + + 20 + + + Qt::Horizontal + + + + + + + 20 + + + + + + + + + Samples rate + + + 48000 + + + + + + + + + Addr + + + + + + + Remote address + + + 000.000.000.000 + + + 127.0.0.1 + + + + + + + D + + + + + + + Remote data port + + + 00000 + + + 9999 + + + + + + + + + + + 15 + 160 + 231 + 156 + + + + Channel Spectrum + + + + 3 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + Sans Serif + 9 + + + + + + + + + + + + + RollupWidget + QWidget +
gui/rollupwidget.h
+ 1 +
+ + GLSpectrum + QWidget +
gui/glspectrum.h
+ 1 +
+ + GLSpectrumGUI + QWidget +
gui/glspectrumgui.h
+ 1 +
+ + ValueDialZ + QWidget +
gui/valuedialz.h
+ 1 +
+
+ + sampleRate + rfBandwidth + + + + + +
diff --git a/plugins/channeltx/udpsink/udpsinkplugin.cpp b/plugins/channeltx/udpsink/udpsinkplugin.cpp new file mode 100644 index 000000000..2162b1ed3 --- /dev/null +++ b/plugins/channeltx/udpsink/udpsinkplugin.cpp @@ -0,0 +1,71 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 F4EXB // +// written by Edouard Griffiths // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "udpsinkplugin.h" + +#include +#include "plugin/pluginapi.h" + +#include "udpsinkgui.h" + +const PluginDescriptor UDPSinkPlugin::m_pluginDescriptor = { + QString("UDP Channel Sink"), + QString("3.6.0"), + QString("(c) Edouard Griffiths, F4EXB"), + QString("https://github.com/f4exb/sdrangel"), + true, + QString("https://github.com/f4exb/sdrangel") +}; + +UDPSinkPlugin::UDPSinkPlugin(QObject* parent) : + QObject(parent), + m_pluginAPI(0) +{ +} + +const PluginDescriptor& UDPSinkPlugin::getPluginDescriptor() const +{ + return m_pluginDescriptor; +} + +void UDPSinkPlugin::initPlugin(PluginAPI* pluginAPI) +{ + m_pluginAPI = pluginAPI; + + // register TCP Channel Source + m_pluginAPI->registerTxChannel(UDPSinkGUI::m_channelID, this); +} + +PluginGUI* UDPSinkPlugin::createTxChannel(const QString& channelName, DeviceSinkAPI *deviceAPI) +{ + if(channelName == UDPSinkGUI::m_channelID) + { + UDPSinkGUI* gui = UDPSinkGUI::create(m_pluginAPI, deviceAPI); +// deviceAPI->registerChannelInstance("sdrangel.channel.udpsrc", gui); +// m_pluginAPI->addChannelRollup(gui); + return gui; + } else { + return 0; + } +} + +void UDPSinkPlugin::createInstanceUDPSink(DeviceSinkAPI *deviceAPI) +{ + UDPSinkGUI::create(m_pluginAPI, deviceAPI); +// deviceAPI->registerChannelInstance("sdrangel.channel.udpsrc", gui); +// m_pluginAPI->addChannelRollup(gui); +} diff --git a/plugins/channeltx/udpsink/udpsinkplugin.h b/plugins/channeltx/udpsink/udpsinkplugin.h new file mode 100644 index 000000000..2ca6624df --- /dev/null +++ b/plugins/channeltx/udpsink/udpsinkplugin.h @@ -0,0 +1,48 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 F4EXB // +// written by Edouard Griffiths // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_UDPSINKPLUGIN_H +#define INCLUDE_UDPSINKPLUGIN_H + +#include +#include "plugin/plugininterface.h" + +class DeviceSinkAPI; + +class UDPSinkPlugin : public QObject, PluginInterface { + Q_OBJECT + Q_INTERFACES(PluginInterface) + Q_PLUGIN_METADATA(IID "sdrangel.channeltx.udpsink") + +public: + explicit UDPSinkPlugin(QObject* parent = 0); + + const PluginDescriptor& getPluginDescriptor() const; + void initPlugin(PluginAPI* pluginAPI); + + PluginGUI* createTxChannel(const QString& channelName, DeviceSinkAPI *deviceAPI); + +private: + static const PluginDescriptor m_pluginDescriptor; + + PluginAPI* m_pluginAPI; + +private slots: + void createInstanceUDPSink(DeviceSinkAPI *deviceAPI); +}; + +#endif // INCLUDE_UDPSINKPLUGIN_H