From 9fd7152f13157f88136a386779919ce57ac59e2b Mon Sep 17 00:00:00 2001 From: Christian Daniel Date: Mon, 23 Sep 2013 21:31:54 +0200 Subject: [PATCH] major rewrite and changes... far too many to put into individual commits --- CMakeLists.txt | 22 +- include-gpl/gui/buttonswitch.h | 19 ++ include-gpl/gui/channelwindow.h | 25 ++ include-gpl/gui/glscope.h | 3 +- include-gpl/gui/glspectrum.h | 7 +- include-gpl/gui/glspectrumgui.h | 4 +- include-gpl/mainwindow.h | 5 +- include-gpl/plugin/pluginmanager.h | 39 ++- include-gpl/settings/preset.h | 22 +- include/gui/rollupwidget.h | 28 +++ include/plugin/pluginapi.h | 9 +- include/plugin/plugingui.h | 8 +- include/plugin/plugininterface.h | 2 +- main.cpp | 60 ++++- plugins/demod/CMakeLists.txt | 5 +- plugins/demod/nfm/nfmdemod.cpp | 11 +- plugins/demod/nfm/nfmdemodgui.cpp | 2 +- plugins/demod/tcpsrc/CMakeLists.txt | 47 ++++ plugins/demod/tcpsrc/tcpsrc.cpp | 82 +++++++ plugins/demod/tcpsrc/tcpsrc.h | 66 +++++ plugins/demod/tcpsrc/tcpsrcgui.cpp | 147 +++++++++++ plugins/demod/tcpsrc/tcpsrcgui.h | 59 +++++ plugins/demod/tcpsrc/tcpsrcgui.ui | 198 +++++++++++++++ plugins/demod/tcpsrc/tcpsrcplugin.cpp | 55 +++++ plugins/demod/tcpsrc/tcpsrcplugin.h | 29 +++ plugins/demod/tetra/tetrademodgui.cpp | 2 +- plugins/samplesource/osmosdr/osmosdrgui.cpp | 7 +- plugins/samplesource/osmosdr/osmosdrgui.h | 12 +- plugins/samplesource/osmosdr/osmosdrgui.ui | 7 +- .../samplesource/osmosdr/osmosdrplugin.cpp | 6 +- plugins/samplesource/rtlsdr/rtlsdrgui.cpp | 7 +- plugins/samplesource/rtlsdr/rtlsdrgui.h | 4 +- plugins/samplesource/rtlsdr/rtlsdrplugin.cpp | 4 +- sdrbase/gui/aboutdialog.ui | 26 +- sdrbase/gui/buttonswitch.cpp | 21 ++ sdrbase/gui/channelwindow.cpp | 36 +++ sdrbase/gui/glscope.cpp | 16 ++ sdrbase/gui/glspectrum.cpp | 86 ++++--- sdrbase/gui/glspectrumgui.cpp | 20 +- sdrbase/gui/glspectrumgui.ui | 27 +- sdrbase/gui/indicator.cpp | 1 + sdrbase/gui/preferencesdialog.ui | 2 +- sdrbase/gui/rollupwidget.cpp | 231 ++++++++++++++++++ sdrbase/gui/scopewindow.cpp | 4 + sdrbase/gui/scopewindow.ui | 5 + sdrbase/mainwindow.cpp | 19 +- sdrbase/mainwindow.ui | 92 +++---- sdrbase/plugin/pluginapi.cpp | 23 +- sdrbase/plugin/plugingui.cpp | 10 - sdrbase/plugin/pluginmanager.cpp | 105 ++++---- sdrbase/resources/histogram.png | Bin 1364 -> 1160 bytes sdrbase/resources/livespectrum.png | Bin 1093 -> 0 bytes sdrbase/resources/maxhold.png | Bin 0 -> 594 bytes sdrbase/resources/res.qrc | 2 +- sdrbase/resources/waterfall.png | Bin 1362 -> 1368 bytes sdrbase/settings/preset.cpp | 22 +- 56 files changed, 1456 insertions(+), 295 deletions(-) create mode 100644 include-gpl/gui/buttonswitch.h create mode 100644 include-gpl/gui/channelwindow.h create mode 100644 include/gui/rollupwidget.h create mode 100644 plugins/demod/tcpsrc/CMakeLists.txt create mode 100644 plugins/demod/tcpsrc/tcpsrc.cpp create mode 100644 plugins/demod/tcpsrc/tcpsrc.h create mode 100644 plugins/demod/tcpsrc/tcpsrcgui.cpp create mode 100644 plugins/demod/tcpsrc/tcpsrcgui.h create mode 100644 plugins/demod/tcpsrc/tcpsrcgui.ui create mode 100644 plugins/demod/tcpsrc/tcpsrcplugin.cpp create mode 100644 plugins/demod/tcpsrc/tcpsrcplugin.h create mode 100644 sdrbase/gui/buttonswitch.cpp create mode 100644 sdrbase/gui/channelwindow.cpp create mode 100644 sdrbase/gui/rollupwidget.cpp delete mode 100644 sdrbase/resources/livespectrum.png create mode 100644 sdrbase/resources/maxhold.png diff --git a/CMakeLists.txt b/CMakeLists.txt index ee9f7f5..2e36db3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,9 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) project(sdrangelove) -set(CMAKE_BUILD_TYPE "Release") +#set(CMAKE_BUILD_TYPE "Release") +#set(CMAKE_BUILD_TYPE "ReleaseWithDebInfo") +set(CMAKE_BUILD_TYPE "Debug") set(QT_USE_QTOPENGL TRUE) set(CMAKE_AUTOMOC ON) @@ -24,12 +26,12 @@ find_package(FFTW3F) add_definitions(${QT_DEFINITIONS}) if(MSVC) -foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) -string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin_${OUTPUTCONFIG}) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin_${OUTPUTCONFIG}) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin_${OUTPUTCONFIG}) -endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES) + foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin_${OUTPUTCONFIG}) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin_${OUTPUTCONFIG}) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin_${OUTPUTCONFIG}) + endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES) endif() ############################################################################## @@ -61,6 +63,8 @@ set(sdrbase_SOURCES sdrbase/gui/aboutdialog.cpp sdrbase/gui/addpresetdialog.cpp + sdrbase/gui/buttonswitch.cpp + sdrbase/gui/channelwindow.cpp sdrbase/gui/glscope.cpp sdrbase/gui/glspectrum.cpp sdrbase/gui/glspectrumgui.cpp @@ -68,6 +72,7 @@ set(sdrbase_SOURCES sdrbase/gui/pluginsdialog.cpp sdrbase/gui/preferencesdialog.cpp sdrbase/gui/presetitem.cpp + sdrbase/gui/rollupwidget.cpp sdrbase/gui/scale.cpp sdrbase/gui/scaleengine.cpp sdrbase/gui/scopewindow.cpp @@ -119,6 +124,8 @@ set(sdrbase_HEADERS include-gpl/gui/aboutdialog.h include-gpl/gui/addpresetdialog.h + include-gpl/gui/buttonswitch.h + include-gpl/gui/channelwindow.h include-gpl/gui/glscope.h include-gpl/gui/glspectrum.h include-gpl/gui/glspectrumgui.h @@ -127,6 +134,7 @@ set(sdrbase_HEADERS include-gpl/gui/pluginsdialog.h include-gpl/gui/preferencesdialog.h include-gpl/gui/presetitem.h + include/gui/rollupwidget.h include-gpl/gui/scale.h include-gpl/gui/scaleengine.h include-gpl/gui/scopewindow.h diff --git a/include-gpl/gui/buttonswitch.h b/include-gpl/gui/buttonswitch.h new file mode 100644 index 0000000..672a5af --- /dev/null +++ b/include-gpl/gui/buttonswitch.h @@ -0,0 +1,19 @@ +#ifndef INCLUDE_BUTTONSWITCH_H +#define INCLUDE_BUTTONSWITCH_H + +#include + +class ButtonSwitch : public QToolButton { + Q_OBJECT + +public: + ButtonSwitch(QWidget* parent = NULL); + +private slots: + void onToggled(bool checked); + +private: + QPalette m_originalPalette; +}; + +#endif // INCLUDE_BUTTONSWITCH_H diff --git a/include-gpl/gui/channelwindow.h b/include-gpl/gui/channelwindow.h new file mode 100644 index 0000000..6bc87e3 --- /dev/null +++ b/include-gpl/gui/channelwindow.h @@ -0,0 +1,25 @@ +#ifndef INCLUDE_CHANNELWINDOW_H +#define INCLUDE_CHANNELWINDOW_H + +#include + +class QBoxLayout; +class QSpacerItem; +class RollupWidget; + +class ChannelWindow : public QScrollArea { + Q_OBJECT + +public: + ChannelWindow(QWidget* parent = NULL); + + void addRollupWidget(QWidget* rollupWidget); + +protected: + QWidget* m_container; + QBoxLayout* m_layout; + + void resizeEvent(QResizeEvent* event); +}; + +#endif // INCLUDE_CHANNELWINDOW_H diff --git a/include-gpl/gui/glscope.h b/include-gpl/gui/glscope.h index 06f66f0..62671c4 100644 --- a/include-gpl/gui/glscope.h +++ b/include-gpl/gui/glscope.h @@ -37,7 +37,8 @@ public: ModeIQ, ModeMagLinPha, ModeMagdBPha, - ModeDerived12 + ModeDerived12, + ModeCyclostationary }; GLScope(QWidget* parent = NULL); diff --git a/include-gpl/gui/glspectrum.h b/include-gpl/gui/glspectrum.h index 9bb3130..e5e05f0 100644 --- a/include-gpl/gui/glspectrum.h +++ b/include-gpl/gui/glspectrum.h @@ -39,7 +39,7 @@ public: void setPowerRange(Real powerRange); void setDisplayWaterfall(bool display); void setInvertedWaterfall(bool inv); - void setDisplayLiveSpectrum(bool display); + void setDisplayMaxHold(bool display); void setDisplayHistogram(bool display); void addChannelMarker(ChannelMarker* channelMarker); @@ -84,9 +84,8 @@ private: bool m_invertedWaterfall; - std::vector m_liveSpectrum; - bool m_displayLiveSpectrum; - bool m_liveSpectrumChanged; + std::vector m_maxHold; + bool m_displayMaxHold; Real m_waterfallShare; diff --git a/include-gpl/gui/glspectrumgui.h b/include-gpl/gui/glspectrumgui.h index b7dc776..3fccab0 100644 --- a/include-gpl/gui/glspectrumgui.h +++ b/include-gpl/gui/glspectrumgui.h @@ -40,7 +40,7 @@ private: Real m_powerRange; bool m_displayWaterfall; bool m_invertedWaterfall; - bool m_displayLiveSpectrum; + bool m_displayMaxHold; bool m_displayHistogram; void applySettings(); @@ -53,7 +53,7 @@ private slots: void on_decay_valueChanged(int value); void on_waterfall_toggled(bool checked); void on_histogram_toggled(bool checked); - void on_liveSpectrum_toggled(bool checked); + void on_maxHold_toggled(bool checked); }; #endif // INCLUDE_GLSPECTRUMGUI_H diff --git a/include-gpl/mainwindow.h b/include-gpl/mainwindow.h index c7396d5..0f0b481 100644 --- a/include-gpl/mainwindow.h +++ b/include-gpl/mainwindow.h @@ -53,7 +53,8 @@ public: MessageQueue* getMessageQueue() { return m_messageQueue; } - void addDemodCreateAction(QAction* action); + void addChannelCreateAction(QAction* action); + void addChannelRollup(QWidget* widget); void addViewAction(QAction* action); void addChannelMarker(ChannelMarker* channelMarker); @@ -67,7 +68,7 @@ private: PItem }; - Ui::MainWindow *ui; + Ui::MainWindow* ui; AudioDeviceInfo* m_audioDeviceInfo; diff --git a/include-gpl/plugin/pluginmanager.h b/include-gpl/plugin/pluginmanager.h index 7586654..8080b5a 100644 --- a/include-gpl/plugin/pluginmanager.h +++ b/include-gpl/plugin/pluginmanager.h @@ -37,8 +37,10 @@ public: const Plugins& getPlugins() const { return m_plugins; } - void registerDemodulator(const QString& demodName, PluginInterface* plugin, QAction* action); - void registerDemodulatorInstance(const QString& demodName, PluginGUI* pluginGUI); + void registerChannel(const QString& channelName, PluginInterface* plugin, QAction* action); + void registerChannelInstance(const QString& channelName, PluginGUI* pluginGUI); + void addChannelRollup(QWidget* pluginGUI); + void removeChannelInstance(PluginGUI* pluginGUI); void registerSampleSource(const QString& sourceName, PluginInterface* plugin); @@ -54,33 +56,30 @@ public: int selectSampleSource(int index); int selectSampleSource(const QString& source); -private slots: - void demodInstanceDestroyed(QObject* object); - private: - struct DemodRegistration { - QString m_demodName; + struct ChannelRegistration { + QString m_channelName; PluginInterface* m_plugin; - DemodRegistration(const QString& demodName, PluginInterface* plugin) : - m_demodName(demodName), + ChannelRegistration(const QString& channelName, PluginInterface* plugin) : + m_channelName(channelName), m_plugin(plugin) { } }; - typedef QList DemodRegistrations; + typedef QList ChannelRegistrations; - struct DemodInstanceRegistration { - QString m_demodName; + struct ChannelInstanceRegistration { + QString m_channelName; PluginGUI* m_gui; - DemodInstanceRegistration() : - m_demodName(), + ChannelInstanceRegistration() : + m_channelName(), m_gui(NULL) { } - DemodInstanceRegistration(const QString& demodName, PluginGUI* pluginGUI) : - m_demodName(demodName), + ChannelInstanceRegistration(const QString& channelName, PluginGUI* pluginGUI) : + m_channelName(channelName), m_gui(pluginGUI) { } }; - typedef QList DemodInstanceRegistrations; + typedef QList ChannelInstanceRegistrations; struct SampleSourceRegistration { QString m_sourceName; @@ -112,8 +111,8 @@ private: DSPEngine* m_dspEngine; Plugins m_plugins; - DemodRegistrations m_demodRegistrations; - DemodInstanceRegistrations m_demodInstanceRegistrations; + ChannelRegistrations m_channelRegistrations; + ChannelInstanceRegistrations m_channelInstanceRegistrations; SampleSourceRegistrations m_sampleSourceRegistrations; SampleSourceDevices m_sampleSourceDevices; @@ -121,7 +120,7 @@ private: PluginGUI* m_sampleSourceInstance; void loadPlugins(const QDir& dir); - void renameDemodInstances(); + void renameChannelInstances(); }; static inline bool operator<(const PluginManager::Plugin& a, const PluginManager::Plugin& b) diff --git a/include-gpl/settings/preset.h b/include-gpl/settings/preset.h index f872941..1396e23 100644 --- a/include-gpl/settings/preset.h +++ b/include-gpl/settings/preset.h @@ -7,16 +7,16 @@ class Preset { public: - struct DemodConfig { - QString m_demod; + struct ChannelConfig { + QString m_channel; QByteArray m_config; - DemodConfig(const QString& demod, const QByteArray& config) : - m_demod(demod), + ChannelConfig(const QString& channel, const QByteArray& config) : + m_channel(channel), m_config(config) { } }; - typedef QList DemodConfigs; + typedef QList ChannelConfigs; Preset(); @@ -49,10 +49,10 @@ public: void setScopeConfig(const QByteArray& data) { m_scopeConfig = data; } const QByteArray& getScopeConfig() const { return m_scopeConfig; } - void clearDemods() { m_demodConfigs.clear(); } - void addDemod(const QString& demod, const QByteArray& config) { m_demodConfigs.append(DemodConfig(demod, config)); } - int getDemodCount() const { return m_demodConfigs.count(); } - const DemodConfig& getDemodConfig(int index) const { return m_demodConfigs.at(index); } + void clearChannels() { m_channelConfigs.clear(); } + void addChannel(const QString& channel, const QByteArray& config) { m_channelConfigs.append(ChannelConfig(channel, config)); } + int getChannelCount() const { return m_channelConfigs.count(); } + const ChannelConfig& getChannelConfig(int index) const { return m_channelConfigs.at(index); } void setSourceConfig(const QString& source, const QByteArray& generalConfig, const QByteArray& config) { @@ -86,8 +86,8 @@ protected: QByteArray m_sourceGeneralConfig; QByteArray m_sourceConfig; - // demodulators and configurations - DemodConfigs m_demodConfigs; + // channels and configurations + ChannelConfigs m_channelConfigs; // screen and dock layout QByteArray m_layout; diff --git a/include/gui/rollupwidget.h b/include/gui/rollupwidget.h new file mode 100644 index 0000000..baba1bf --- /dev/null +++ b/include/gui/rollupwidget.h @@ -0,0 +1,28 @@ +#ifndef INCLUDE_DEMODWIDGET_H +#define INCLUDE_DEMODWIDGET_H + +#include + +class RollupWidget : public QWidget { + Q_OBJECT + +public: + RollupWidget(QWidget* parent = NULL); + + void addRollup(QWidget* rollup); + +protected: + //QWidgetList m_rollups; + + int arrangeRollups(); + + void paintEvent(QPaintEvent*); + int paintRollup(QWidget* rollup, int pos, QPainter* p, bool last, const QColor& frame); + + void resizeEvent(QResizeEvent* size); + void mousePressEvent(QMouseEvent* event); + + bool eventFilter(QObject* object, QEvent* event); +}; + +#endif // INCLUDE_DEMODWIDGET_H diff --git a/include/plugin/pluginapi.h b/include/plugin/pluginapi.h index e1cfb1a..d37a6b7 100644 --- a/include/plugin/pluginapi.h +++ b/include/plugin/pluginapi.h @@ -25,10 +25,13 @@ public: // MainWindow access QDockWidget* createMainWindowDock(Qt::DockWidgetArea dockWidgetArea, const QString& title); MessageQueue* getMainWindowMessageQueue(); + void setInputGUI(QWidget* inputGUI); - // Demodulator stuff - void registerDemodulator(const QString& demodName, PluginInterface* plugin, QAction* action); - void registerDemodulatorInstance(const QString& demodName, PluginGUI* pluginGUI); + // Channel stuff + void registerChannel(const QString& channelName, PluginInterface* plugin, QAction* action); + void registerChannelInstance(const QString& channelName, PluginGUI* pluginGUI); + void addChannelRollup(QWidget* pluginGUI); + void removeChannelInstance(PluginGUI* pluginGUI); void addChannelMarker(ChannelMarker* channelMarker); void removeChannelMarker(ChannelMarker* channelMarker); diff --git a/include/plugin/plugingui.h b/include/plugin/plugingui.h index 9af77ec..586e446 100644 --- a/include/plugin/plugingui.h +++ b/include/plugin/plugingui.h @@ -6,14 +6,12 @@ class Message; -class SDRANGELOVE_API PluginGUI : public QWidget { - Q_OBJECT - +class SDRANGELOVE_API PluginGUI { public: - PluginGUI(QWidget* parent = NULL); + PluginGUI() { }; virtual void destroy() = 0; - virtual void setWidgetName(const QString& name); + virtual void setName(const QString& name) = 0; virtual void resetToDefaults() = 0; diff --git a/include/plugin/plugininterface.h b/include/plugin/plugininterface.h index f99009d..edf3f47 100644 --- a/include/plugin/plugininterface.h +++ b/include/plugin/plugininterface.h @@ -37,7 +37,7 @@ public: virtual const PluginDescriptor& getPluginDescriptor() const = 0; virtual void initPlugin(PluginAPI* pluginAPI) = 0; - virtual PluginGUI* createDemod(const QString& demodName) { return NULL; } + virtual PluginGUI* createChannel(const QString& channelName) { return NULL; } virtual SampleSourceDevices enumSampleSources() { return SampleSourceDevices(); } virtual PluginGUI* createSampleSource(const QString& sourceName, const QByteArray& address) { return NULL; } diff --git a/main.cpp b/main.cpp index 4ceadfb..ce305f5 100644 --- a/main.cpp +++ b/main.cpp @@ -19,37 +19,73 @@ #include #include #include +#include #include "mainwindow.h" static int runQtApplication(int argc, char* argv[]) { QApplication a(argc, argv); - - /*QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); - QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));*/ - +/* + QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); +*/ QCoreApplication::setOrganizationName("osmocom"); QCoreApplication::setApplicationName("SDRangelove"); - //QApplication::setStyle(new QProxyStyle()); -#if 0 +#if 1 qApp->setStyle(QStyleFactory::create("fusion")); QPalette palette; palette.setColor(QPalette::Window, QColor(53,53,53)); palette.setColor(QPalette::WindowText, Qt::white); - palette.setColor(QPalette::Base, QColor(15,15,15)); + palette.setColor(QPalette::Base, QColor(25,25,25)); palette.setColor(QPalette::AlternateBase, QColor(53,53,53)); palette.setColor(QPalette::ToolTipBase, Qt::white); - palette.setColor(QPalette::ToolTipText, Qt::white); + palette.setColor(QPalette::ToolTipText, Qt::black); palette.setColor(QPalette::Text, Qt::white); - palette.setColor(QPalette::Button, QColor(53,53,53)); + palette.setColor(QPalette::Button, QColor(0x40, 0x40, 0x40)); palette.setColor(QPalette::ButtonText, Qt::white); palette.setColor(QPalette::BrightText, Qt::red); - palette.setColor(QPalette::Highlight, QColor(142,45,197).lighter()); + palette.setColor(QPalette::Light, QColor(53,53,53).lighter(125).lighter()); + palette.setColor(QPalette::Mid, QColor(53,53,53).lighter(125)); + palette.setColor(QPalette::Dark, QColor(53,53,53).lighter(125).darker()); + + palette.setColor(QPalette::Link, QColor(0,0xa0,0xa0)); + palette.setColor(QPalette::LinkVisited, QColor(0,0xa0,0xa0).lighter()); + palette.setColor(QPalette::Highlight, QColor(0xff, 0x8c, 0x00)); palette.setColor(QPalette::HighlightedText, Qt::black); qApp->setPalette(palette); + +#if 0 + if(QFontDatabase::addApplicationFont("/tmp/Cuprum.otf") >= 0) { + QFont font("CuprumFFU"); + font.setPointSize(10); + qApp->setFont(font); + } +#endif +#if 0 + if(QFontDatabase::addApplicationFont("/tmp/PTN57F.ttf") >= 0) { + QFont font("PT Sans Narrow"); + font.setPointSize(10); + qApp->setFont(font); + } +#endif +#if 0 + if(QFontDatabase::addApplicationFont("/tmp/PTS55F.ttf") >= 0) { + QFont font("PT Sans"); + font.setPointSize(10); + qApp->setFont(font); + } +#endif +#if 0 + { + QFont font("Ubuntu Condensed"); + font.setPointSize(10); + qApp->setFont(font); + } +#endif + #endif MainWindow w; w.show(); @@ -59,5 +95,7 @@ static int runQtApplication(int argc, char* argv[]) int main(int argc, char* argv[]) { - return runQtApplication(argc, argv); + int res = runQtApplication(argc, argv); + qDebug("regular program exit"); + return res; } diff --git a/plugins/demod/CMakeLists.txt b/plugins/demod/CMakeLists.txt index 78804e6..19c7962 100644 --- a/plugins/demod/CMakeLists.txt +++ b/plugins/demod/CMakeLists.txt @@ -1,4 +1,5 @@ project(demod) -add_subdirectory(nfm) -add_subdirectory(tetra) +#add_subdirectory(nfm) +add_subdirectory(tcpsrc) +#add_subdirectory(tetra) diff --git a/plugins/demod/nfm/nfmdemod.cpp b/plugins/demod/nfm/nfmdemod.cpp index 6330a16..fde579b 100644 --- a/plugins/demod/nfm/nfmdemod.cpp +++ b/plugins/demod/nfm/nfmdemod.cpp @@ -58,8 +58,6 @@ void NFMDemod::configure(MessageQueue* messageQueue, Real rfBandwidth, Real afBa void NFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst) { - size_t count = end - begin; - Complex ci; bool consumed; @@ -74,7 +72,7 @@ void NFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iter m_movingAverage.feed(ci.real() * ci.real() + ci.imag() * ci.imag()); if(m_movingAverage.average() >= m_squelchLevel) - m_squelchState = m_sampleRate / 100; + m_squelchState = m_sampleRate / 50; if(m_squelchState > 0) { m_squelchState--; @@ -89,8 +87,11 @@ void NFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iter m_audioBuffer[m_audioBufferFill].r = sample; ++m_audioBufferFill; if(m_audioBufferFill >= m_audioBuffer.size()) { - if(m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 0) != m_audioBufferFill) - ;//qDebug("lost samples"); + uint res = m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1); + /* + if(res != m_audioBufferFill) + qDebug("lost %u samples", m_audioBufferFill - res); + */ m_audioBufferFill = 0; } } diff --git a/plugins/demod/nfm/nfmdemodgui.cpp b/plugins/demod/nfm/nfmdemodgui.cpp index a630dd4..d507cfd 100644 --- a/plugins/demod/nfm/nfmdemodgui.cpp +++ b/plugins/demod/nfm/nfmdemodgui.cpp @@ -139,7 +139,7 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, QDockWidget* dockWidget, QWidget* ui->glSpectrum->setCenterFrequency(0); ui->glSpectrum->setSampleRate(44100); ui->glSpectrum->setDisplayWaterfall(true); - ui->glSpectrum->setDisplayLiveSpectrum(true); + ui->glSpectrum->setDisplayMaxHold(true); m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris); m_channelMarker = new ChannelMarker(this); diff --git a/plugins/demod/tcpsrc/CMakeLists.txt b/plugins/demod/tcpsrc/CMakeLists.txt new file mode 100644 index 0000000..df7c4d4 --- /dev/null +++ b/plugins/demod/tcpsrc/CMakeLists.txt @@ -0,0 +1,47 @@ +project(tcpsrc) + +set(tcpsrc_SOURCES + tcpsrc.cpp + tcpsrcgui.cpp + tcpsrcplugin.cpp +) + +set(tcpsrc_HEADERS + tcpsrc.h + tcpsrcgui.h + tcpsrcplugin.h +) + +set(tcpsrc_FORMS + tcpsrcgui.ui +) + +include_directories( + . + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/include-gpl + ${OPENGL_INCLUDE_DIR} +) + +#include(${QT_USE_FILE}) +add_definitions(${QT_DEFINITIONS}) +add_definitions(-DQT_PLUGIN) +add_definitions(-DQT_SHARED) + +#qt5_wrap_cpp(tcpsrc_HEADERS_MOC ${tcpsrc_HEADERS}) +qt5_wrap_ui(tcpsrc_FORMS_HEADERS ${tcpsrc_FORMS}) + +add_library(demodtcpsrc SHARED + ${tcpsrc_SOURCES} + ${tcpsrc_HEADERS_MOC} + ${tcpsrc_FORMS_HEADERS} +) + +target_link_libraries(demodtcpsrc + ${QT_LIBRARIES} + ${OPENGL_LIBRARIES} + sdrbase +) + +qt5_use_modules(demodtcpsrc Core Widgets OpenGL Network) diff --git a/plugins/demod/tcpsrc/tcpsrc.cpp b/plugins/demod/tcpsrc/tcpsrc.cpp new file mode 100644 index 0000000..6ed4194 --- /dev/null +++ b/plugins/demod/tcpsrc/tcpsrc.cpp @@ -0,0 +1,82 @@ +#include "tcpsrc.h" +#include "dsp/dspcommands.h" + +MessageRegistrator TCPSrc::MsgConfigureTCPSrc::ID("MsgConfigureTCPSrc"); + +TCPSrc::TCPSrc(SampleSink* spectrum) +{ + m_inputSampleRate = 100000; + m_sampleFormat = 0; + m_outputSampleRate = 50000; + m_rfBandwidth = 50000; + m_tcpPort = 9999; + m_nco.setFreq(0, m_inputSampleRate); + m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.1); + m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate; + m_spectrum = spectrum; +} + +TCPSrc::~TCPSrc() +{ +} + +void TCPSrc::configure(MessageQueue* messageQueue, int sampleFormat, Real outputSampleRate, Real rfBandwidth, int tcpPort) +{ + Message* cmd = MsgConfigureTCPSrc::create(sampleFormat, outputSampleRate, rfBandwidth, tcpPort); + cmd->submit(messageQueue, this); +} + +void TCPSrc::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst) +{ + Complex ci; + bool consumed; + + for(SampleVector::const_iterator it = begin; it < end; ++it) { + Complex c(it->real() / 32768.0, it->imag() / 32768.0); + c *= m_nco.nextIQ(); + + consumed = false; + if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &consumed, &ci)) { + m_sampleBuffer.push_back(Sample(ci.real() * 32768.0, ci.imag() * 32768.0)); + m_sampleDistanceRemain += m_inputSampleRate / m_outputSampleRate; + } + } + + if(m_spectrum != NULL) + m_spectrum->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), firstOfBurst); + m_sampleBuffer.clear(); +} + +void TCPSrc::start() +{ +} + +void TCPSrc::stop() +{ +} + +bool TCPSrc::handleMessage(Message* cmd) +{ + if(cmd->id() == DSPSignalNotification::ID()) { + DSPSignalNotification* signal = (DSPSignalNotification*)cmd; + qDebug("%d samples/sec, %lld Hz offset", signal->getSampleRate(), signal->getFrequencyOffset()); + m_inputSampleRate = signal->getSampleRate(); + m_nco.setFreq(-signal->getFrequencyOffset(), m_inputSampleRate); + m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.1); + m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate; + cmd->completed(); + return true; + } else if(cmd->id() == MsgConfigureTCPSrc::ID()) { + MsgConfigureTCPSrc* cfg = (MsgConfigureTCPSrc*)cmd; + m_sampleFormat = cfg->getSampleFormat(); + m_outputSampleRate = cfg->getOutputSampleRate(); + m_rfBandwidth = cfg->getRFBandwidth(); + m_tcpPort = cfg->getTCPPort(); + m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.1); + m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate; + cmd->completed(); + return true; + } else { + return false; + } +} diff --git a/plugins/demod/tcpsrc/tcpsrc.h b/plugins/demod/tcpsrc/tcpsrc.h new file mode 100644 index 0000000..895a555 --- /dev/null +++ b/plugins/demod/tcpsrc/tcpsrc.h @@ -0,0 +1,66 @@ +#ifndef INCLUDE_TCPSRC_H +#define INCLUDE_TCPSRC_H + +#include "dsp/samplesink.h" +#include "dsp/nco.h" +#include "dsp/interpolator.h" +#include "util/message.h" + +class TCPSrc : public SampleSink { +public: + TCPSrc(SampleSink* spectrum); + ~TCPSrc(); + + void configure(MessageQueue* messageQueue, int sampleFormat, Real outputSampleRate, Real rfBandwidth, int tcpPort); + + void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst); + void start(); + void stop(); + bool handleMessage(Message* cmd); + +protected: + class MsgConfigureTCPSrc : public Message { + public: + static MessageRegistrator ID; + + int getSampleFormat() const { return m_sampleFormat; } + Real getOutputSampleRate() const { return m_outputSampleRate; } + Real getRFBandwidth() const { return m_rfBandwidth; } + int getTCPPort() const { return m_tcpPort; } + + static MsgConfigureTCPSrc* create(int sampleFormat, Real sampleRate, Real rfBandwidth, int tcpPort) + { + return new MsgConfigureTCPSrc(sampleFormat, sampleRate, rfBandwidth, tcpPort); + } + + private: + int m_sampleFormat; + Real m_outputSampleRate; + Real m_rfBandwidth; + int m_tcpPort; + + MsgConfigureTCPSrc(int sampleFormat, Real outputSampleRate, Real rfBandwidth, int tcpPort) : + Message(ID()), + m_sampleFormat(sampleFormat), + m_outputSampleRate(outputSampleRate), + m_rfBandwidth(rfBandwidth), + m_tcpPort(tcpPort) + { } + }; + + int m_inputSampleRate; + + int m_sampleFormat; + Real m_outputSampleRate; + Real m_rfBandwidth; + int m_tcpPort; + + NCO m_nco; + Interpolator m_interpolator; + Real m_sampleDistanceRemain; + + SampleVector m_sampleBuffer; + SampleSink* m_spectrum; +}; + +#endif // INCLUDE_TCPSRC_H diff --git a/plugins/demod/tcpsrc/tcpsrcgui.cpp b/plugins/demod/tcpsrc/tcpsrcgui.cpp new file mode 100644 index 0000000..3567d03 --- /dev/null +++ b/plugins/demod/tcpsrc/tcpsrcgui.cpp @@ -0,0 +1,147 @@ +#include "tcpsrcgui.h" +#include "plugin/pluginapi.h" +#include "tcpsrc.h" +#include "dsp/channelizer.h" +#include "dsp/spectrumvis.h" +#include "dsp/threadedsamplesink.h" +#include "ui_tcpsrcgui.h" + +TCPSrcGUI* TCPSrcGUI::create(PluginAPI* pluginAPI) +{ + TCPSrcGUI* gui = new TCPSrcGUI(pluginAPI); + return gui; +} + +void TCPSrcGUI::destroy() +{ + delete this; +} + +void TCPSrcGUI::setName(const QString& name) +{ + setObjectName(name); +} + +void TCPSrcGUI::resetToDefaults() +{ + ui->sampleFormat->setCurrentIndex(0); + ui->sampleRate->setText("25000"); + ui->rfBandwidth->setText("20000"); + ui->tcpPort->setText("9999"); + applySettings(); +} + +QByteArray TCPSrcGUI::serialize() const +{ + return QByteArray(); +} + +bool TCPSrcGUI::deserialize(const QByteArray& data) +{ + return false; +} + +bool TCPSrcGUI::handleMessage(Message* message) +{ + return false; +} + +void TCPSrcGUI::channelMarkerChanged() +{ + applySettings(); +} + +TCPSrcGUI::TCPSrcGUI(PluginAPI* pluginAPI, QWidget* parent) : + RollupWidget(parent), + ui(new Ui::TCPSrcGUI), + m_pluginAPI(pluginAPI) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose, true); + + m_spectrumVis = new SpectrumVis(ui->glSpectrum); + m_tcpSrc = new TCPSrc(m_spectrumVis); + m_channelizer = new Channelizer(m_tcpSrc); + m_threadedSampleSink = new ThreadedSampleSink(m_channelizer); + m_pluginAPI->addSampleSink(m_threadedSampleSink); + + ui->glSpectrum->setCenterFrequency(0); + ui->glSpectrum->setSampleRate(ui->sampleRate->text().toInt()); + ui->glSpectrum->setDisplayWaterfall(true); + ui->glSpectrum->setDisplayMaxHold(true); + m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris); + + m_channelMarker = new ChannelMarker(this); + m_channelMarker->setColor(Qt::red); + m_channelMarker->setBandwidth(25000); + m_channelMarker->setCenterFrequency(0); + m_channelMarker->setVisible(true); + connect(m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged())); + m_pluginAPI->addChannelMarker(m_channelMarker); + + applySettings(); +} + +TCPSrcGUI::~TCPSrcGUI() +{ + m_pluginAPI->removeChannelInstance(this); + delete ui; +} + +void TCPSrcGUI::applySettings() +{ + bool ok; + + Real outputSampleRate = ui->sampleRate->text().toDouble(&ok); + if((!ok) || (outputSampleRate < 100)) + outputSampleRate = 25000; + Real rfBandwidth = ui->rfBandwidth->text().toDouble(&ok); + if((!ok) || (rfBandwidth > outputSampleRate)) + rfBandwidth = outputSampleRate / 1.05; + int tcpPort = ui->tcpPort->text().toInt(&ok); + if((!ok) || (tcpPort < 1) || (tcpPort > 65535)) + tcpPort = 9999; + + ui->sampleRate->setText(QString("%1").arg(outputSampleRate, 0)); + ui->rfBandwidth->setText(QString("%1").arg(rfBandwidth, 0)); + ui->tcpPort->setText(QString("%1").arg(tcpPort)); + m_channelMarker->setBandwidth(rfBandwidth); + ui->glSpectrum->setSampleRate(outputSampleRate); + + m_channelizer->configure(m_threadedSampleSink->getMessageQueue(), + outputSampleRate, + m_channelMarker->getCenterFrequency()); + + m_tcpSrc->configure(m_threadedSampleSink->getMessageQueue(), + ui->sampleFormat->currentIndex(), + outputSampleRate, + rfBandwidth, + tcpPort); + + ui->applyBtn->setEnabled(false); +} + +void TCPSrcGUI::on_sampleFormat_currentIndexChanged(int index) +{ + ui->applyBtn->setEnabled(true); +} + +void TCPSrcGUI::on_sampleRate_textEdited(const QString& arg1) +{ + ui->applyBtn->setEnabled(true); +} + +void TCPSrcGUI::on_rfBandwidth_textEdited(const QString& arg1) +{ + ui->applyBtn->setEnabled(true); +} + +void TCPSrcGUI::on_tcpPort_textEdited(const QString& arg1) +{ + ui->applyBtn->setEnabled(true); +} + +void TCPSrcGUI::on_applyBtn_clicked() +{ + applySettings(); +} diff --git a/plugins/demod/tcpsrc/tcpsrcgui.h b/plugins/demod/tcpsrc/tcpsrcgui.h new file mode 100644 index 0000000..f65efe6 --- /dev/null +++ b/plugins/demod/tcpsrc/tcpsrcgui.h @@ -0,0 +1,59 @@ +#ifndef INCLUDE_TCPSRCGUI_H +#define INCLUDE_TCPSRCGUI_H + +#include "gui/rollupwidget.h" +#include "plugin/plugingui.h" + +class PluginAPI; +class ChannelMarker; +class ThreadedSampleSink; +class Channelizer; +class TCPSrc; +class SpectrumVis; + +namespace Ui { + class TCPSrcGUI; +} + +class TCPSrcGUI : public RollupWidget, public PluginGUI { + Q_OBJECT + +public: + static TCPSrcGUI* create(PluginAPI* pluginAPI); + void destroy(); + + void setName(const QString& name); + + void resetToDefaults(); + QByteArray serialize() const; + bool deserialize(const QByteArray& data); + + bool handleMessage(Message* message); + +private slots: + void channelMarkerChanged(); + void on_sampleFormat_currentIndexChanged(int index); + void on_sampleRate_textEdited(const QString& arg1); + void on_rfBandwidth_textEdited(const QString& arg1); + void on_tcpPort_textEdited(const QString& arg1); + + void on_applyBtn_clicked(); + +private: + Ui::TCPSrcGUI* ui; + PluginAPI* m_pluginAPI; + ChannelMarker* m_channelMarker; + + // RF path + ThreadedSampleSink* m_threadedSampleSink; + Channelizer* m_channelizer; + TCPSrc* m_tcpSrc; + SpectrumVis* m_spectrumVis; + + explicit TCPSrcGUI(PluginAPI* pluginAPI, QWidget* parent = NULL); + ~TCPSrcGUI(); + + void applySettings(); +}; + +#endif // INCLUDE_TCPSRCGUI_H diff --git a/plugins/demod/tcpsrc/tcpsrcgui.ui b/plugins/demod/tcpsrc/tcpsrcgui.ui new file mode 100644 index 0000000..12cb079 --- /dev/null +++ b/plugins/demod/tcpsrc/tcpsrcgui.ui @@ -0,0 +1,198 @@ + + + TCPSrcGUI + + + + 0 + 0 + 400 + 443 + + + + TCP Sample Source + + + + + 10 + 5 + 201 + 142 + + + + Settings + + + + 2 + + + 3 + + + + + Sample Format + + + + + + + 9999 + + + + + + + RF Bandwidth + + + + + + + 25000 + + + + + + + 20000 + + + + + + + Samplerate + + + + + + + TCP Port + + + + + + + + S8 I/Q + + + + + S16LE I/Q + + + + + + + + false + + + Apply + + + + + + + + + 15 + 160 + 231 + 156 + + + + Channel Spectrum + + + + 3 + + + 2 + + + + + + + + + + 15 + 330 + 274 + 101 + + + + Connected Clients + + + + 3 + + + 2 + + + + + false + + + false + + + false + + + + IP:Port + + + + + + + + + + RollupWidget + QWidget +
gui/rollupwidget.h
+ 1 +
+ + GLSpectrum + QWidget +
gui/glspectrum.h
+ 1 +
+
+ + sampleFormat + sampleRate + rfBandwidth + tcpPort + applyBtn + treeWidget + + + +
diff --git a/plugins/demod/tcpsrc/tcpsrcplugin.cpp b/plugins/demod/tcpsrc/tcpsrcplugin.cpp new file mode 100644 index 0000000..81b654b --- /dev/null +++ b/plugins/demod/tcpsrc/tcpsrcplugin.cpp @@ -0,0 +1,55 @@ +#include +#include +#include "plugin/pluginapi.h" +#include "tcpsrcplugin.h" +#include "tcpsrcgui.h" + +const PluginDescriptor TCPSrcPlugin::m_pluginDescriptor = { + QString("TCP Channel Source"), + QString("---"), + QString("(c) maintech GmbH (written by Christian Daniel)"), + QString("http://www.maintech.de"), + true, + QString("http://www.maintech.de") +}; + +TCPSrcPlugin::TCPSrcPlugin(QObject* parent) : + QObject(parent) +{ +} + +const PluginDescriptor& TCPSrcPlugin::getPluginDescriptor() const +{ + return m_pluginDescriptor; +} + +void TCPSrcPlugin::initPlugin(PluginAPI* pluginAPI) +{ + m_pluginAPI = pluginAPI; + + // register TCP Channel Source + QAction* action = new QAction(tr("&TCP Source"), this); + connect(action, SIGNAL(triggered()), this, SLOT(createInstanceTCPSrc())); + m_pluginAPI->registerChannel("de.maintech.sdrangelove.channel.tcpsrc", this, action); +} + +PluginGUI* TCPSrcPlugin::createChannel(const QString& channelName) +{ + if(channelName == "de.maintech.sdrangelove.channel.tcpsrc") { + TCPSrcGUI* gui = TCPSrcGUI::create(m_pluginAPI); + m_pluginAPI->registerChannelInstance("de.maintech.sdrangelove.channel.tcpsrc", gui); + m_pluginAPI->addChannelRollup(gui); + return gui; + } else { + return NULL; + } +} + +void TCPSrcPlugin::createInstanceTCPSrc() +{ + TCPSrcGUI* gui = TCPSrcGUI::create(m_pluginAPI); + m_pluginAPI->registerChannelInstance("de.maintech.sdrangelove.channel.tcpsrc", gui); + m_pluginAPI->addChannelRollup(gui); + //m_pluginAPI->registerChannelInstance("de.maintech.sdrangelove.channel.tcpsrc", TCPSrcGUI::create(m_pluginAPI)); +} + diff --git a/plugins/demod/tcpsrc/tcpsrcplugin.h b/plugins/demod/tcpsrc/tcpsrcplugin.h new file mode 100644 index 0000000..984cd8f --- /dev/null +++ b/plugins/demod/tcpsrc/tcpsrcplugin.h @@ -0,0 +1,29 @@ +#ifndef INCLUDE_TCPSRCPLUGIN_H +#define INCLUDE_TCPSRCPLUGIN_H + +#include +#include "plugin/plugininterface.h" + +class TCPSrcPlugin : public QObject, PluginInterface { + Q_OBJECT + Q_INTERFACES(PluginInterface) + Q_PLUGIN_METADATA(IID "de.maintech.sdrangelove.demod.tcpsrc") + +public: + explicit TCPSrcPlugin(QObject* parent = NULL); + + const PluginDescriptor& getPluginDescriptor() const; + void initPlugin(PluginAPI* pluginAPI); + + PluginGUI* createChannel(const QString& channelName); + +private: + static const PluginDescriptor m_pluginDescriptor; + + PluginAPI* m_pluginAPI; + +private slots: + void createInstanceTCPSrc(); +}; + +#endif // INCLUDE_TCPSRCPLUGIN_H diff --git a/plugins/demod/tetra/tetrademodgui.cpp b/plugins/demod/tetra/tetrademodgui.cpp index a0659b5..978f4f7 100644 --- a/plugins/demod/tetra/tetrademodgui.cpp +++ b/plugins/demod/tetra/tetrademodgui.cpp @@ -79,7 +79,7 @@ TetraDemodGUI::TetraDemodGUI(PluginAPI* pluginAPI, QDockWidget* dockWidget, QWid ui->glSpectrum->setCenterFrequency(0); ui->glSpectrum->setSampleRate(36000); ui->glSpectrum->setDisplayWaterfall(true); - ui->glSpectrum->setDisplayLiveSpectrum(true); + ui->glSpectrum->setDisplayMaxHold(true); m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris); m_channelMarker = new ChannelMarker(this); diff --git a/plugins/samplesource/osmosdr/osmosdrgui.cpp b/plugins/samplesource/osmosdr/osmosdrgui.cpp index ddaf4d3..3ecaa35 100644 --- a/plugins/samplesource/osmosdr/osmosdrgui.cpp +++ b/plugins/samplesource/osmosdr/osmosdrgui.cpp @@ -3,7 +3,7 @@ #include "plugin/pluginapi.h" OsmoSDRGui::OsmoSDRGui(PluginAPI* pluginAPI, QWidget* parent) : - PluginGUI(parent), + QWidget(parent), ui(new Ui::OsmoSDRGui), m_pluginAPI(pluginAPI), m_settings(), @@ -28,6 +28,11 @@ void OsmoSDRGui::destroy() delete this; } +void OsmoSDRGui::setName(const QString& name) +{ + setObjectName(name); +} + void OsmoSDRGui::resetToDefaults() { m_generalSettings.resetToDefaults(); diff --git a/plugins/samplesource/osmosdr/osmosdrgui.h b/plugins/samplesource/osmosdr/osmosdrgui.h index 770b48e..f043653 100644 --- a/plugins/samplesource/osmosdr/osmosdrgui.h +++ b/plugins/samplesource/osmosdr/osmosdrgui.h @@ -11,7 +11,7 @@ namespace Ui { class OsmoSDRGui; } -class OsmoSDRGui : public PluginGUI { +class OsmoSDRGui : public QWidget, public PluginGUI { Q_OBJECT public: @@ -19,6 +19,8 @@ public: ~OsmoSDRGui(); void destroy(); + void setName(const QString& name); + void resetToDefaults(); QByteArray serializeGeneral() const; bool deserializeGeneral(const QByteArray&data); @@ -28,14 +30,6 @@ public: bool handleMessage(Message* message); private: - /* - Ui::OsmoSDRGui* ui; - - MessageQueue* m_msgQueue; - OsmoSDRInput::Settings m_settings; - QTimer m_updateTimer; - */ - Ui::OsmoSDRGui* ui; PluginAPI* m_pluginAPI; diff --git a/plugins/samplesource/osmosdr/osmosdrgui.ui b/plugins/samplesource/osmosdr/osmosdrgui.ui index 1ad4a88..e618941 100644 --- a/plugins/samplesource/osmosdr/osmosdrgui.ui +++ b/plugins/samplesource/osmosdr/osmosdrgui.ui @@ -7,7 +7,7 @@ 0 0 253 - 224 + 229 @@ -118,10 +118,7 @@ Qt::Horizontal - QSlider::TicksAbove - - - 1 + QSlider::TicksBelow diff --git a/plugins/samplesource/osmosdr/osmosdrplugin.cpp b/plugins/samplesource/osmosdr/osmosdrplugin.cpp index a61e4c8..183642d 100644 --- a/plugins/samplesource/osmosdr/osmosdrplugin.cpp +++ b/plugins/samplesource/osmosdr/osmosdrplugin.cpp @@ -48,17 +48,21 @@ PluginInterface::SampleSourceDevices OsmoSDRPlugin::enumSampleSources() if(osmosdr_get_device_usb_strings(i, vendor, product, serial) != 0) continue; QString displayedName(QString("OsmoSDR #%1 (#%2)").arg(i + 1).arg(serial)); + qDebug("found %s", qPrintable(displayedName)); SimpleSerializer s(1); s.writeS32(1, i); result.append(SampleSourceDevice(displayedName, "org.osmocom.sdr.samplesource.osmo-sdr", s.final())); } + return result; } PluginGUI* OsmoSDRPlugin::createSampleSource(const QString& sourceName, const QByteArray& address) { if(sourceName == "org.osmocom.sdr.samplesource.osmo-sdr") { - return new OsmoSDRGui(m_pluginAPI); + OsmoSDRGui* gui = new OsmoSDRGui(m_pluginAPI); + m_pluginAPI->setInputGUI(gui); + return gui; } else { return NULL; } diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp index 7f933cf..c7024e2 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp @@ -3,7 +3,7 @@ #include "plugin/pluginapi.h" RTLSDRGui::RTLSDRGui(PluginAPI* pluginAPI, QWidget* parent) : - PluginGUI(parent), + QWidget(parent), ui(new Ui::RTLSDRGui), m_pluginAPI(pluginAPI), m_settings(), @@ -28,6 +28,11 @@ void RTLSDRGui::destroy() delete this; } +void RTLSDRGui::setName(const QString& name) +{ + setObjectName(name); +} + void RTLSDRGui::resetToDefaults() { m_generalSettings.resetToDefaults(); diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.h b/plugins/samplesource/rtlsdr/rtlsdrgui.h index 5a1944d..46b248b 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrgui.h +++ b/plugins/samplesource/rtlsdr/rtlsdrgui.h @@ -11,7 +11,7 @@ namespace Ui { class RTLSDRGui; } -class RTLSDRGui : public PluginGUI { +class RTLSDRGui : public QWidget, public PluginGUI { Q_OBJECT public: @@ -19,6 +19,8 @@ public: ~RTLSDRGui(); void destroy(); + void setName(const QString& name); + void resetToDefaults(); QByteArray serializeGeneral() const; bool deserializeGeneral(const QByteArray&data); diff --git a/plugins/samplesource/rtlsdr/rtlsdrplugin.cpp b/plugins/samplesource/rtlsdr/rtlsdrplugin.cpp index 184a97a..785aa2d 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrplugin.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrplugin.cpp @@ -58,7 +58,9 @@ PluginInterface::SampleSourceDevices RTLSDRPlugin::enumSampleSources() PluginGUI* RTLSDRPlugin::createSampleSource(const QString& sourceName, const QByteArray& address) { if(sourceName == "org.osmocom.sdr.samplesource.rtl-sdr") { - return new RTLSDRGui(m_pluginAPI); + RTLSDRGui* gui = new RTLSDRGui(m_pluginAPI); + m_pluginAPI->setInputGUI(gui); + return gui; } else { return NULL; } diff --git a/sdrbase/gui/aboutdialog.ui b/sdrbase/gui/aboutdialog.ui index ff5a4e4..0e0c182 100644 --- a/sdrbase/gui/aboutdialog.ui +++ b/sdrbase/gui/aboutdialog.ui @@ -6,8 +6,8 @@ 0 0 - 476 - 499 + 484 + 503 @@ -78,19 +78,15 @@ - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Ubuntu'; font-size:8pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Höchberg, Germany<br />Written by Christian Daniel.</p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Many thanks to the osmocom developer team - especially horizon, Hoernchen &amp; tnt.</p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">SDRangelove itself is licensed as &quot;GPL2+&quot; with the added exception, that plugins using only header files from the &quot;include&quot;-subdirectory and not from the &quot;include-gpl&quot;-subdirectory do not count as derived works.</p> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The following rules apply to the SDRangelove main application and libsdrbase:</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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; either version 2 of the License, or (at your option) any later version.</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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.</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">You should have received a copy of the GNU General Public License along with this program. If not, see <a href="http://www.gnu.org/licenses/"><span style=" text-decoration: underline; color:#502878;">http://www.gnu.org/licenses/</span></a></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; text-decoration: underline; color:#502878;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For the license of installed plugins, look into the plugin list.</p></body></html> + <p>Copyright (C) 2013 maintech GmbH, Otto-Hahn-Str. 15, 97204 Höchberg, Germany<br> +Written by Christian Daniel.</p> +<p>Many thanks to the osmocom developer team - especially horizon, Hoernchen &amp; tnt.</p> +<p>SDRangelove itself is licensed as "GPL2+" with the added exception, that plugins using only header files from the "include"-subdirectory and not from the "include-gpl"-subdirectory do not count as derived works.</p> +<p>The following rules apply to the SDRangelove main application and libsdrbase:<br> +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; either version 2 of the License, or (at your option) any later version. +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. +You should have received a copy of the GNU General Public License along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p> +<p>For the license of installed plugins, look into the plugin list.</p> true diff --git a/sdrbase/gui/buttonswitch.cpp b/sdrbase/gui/buttonswitch.cpp new file mode 100644 index 0000000..88d0bd5 --- /dev/null +++ b/sdrbase/gui/buttonswitch.cpp @@ -0,0 +1,21 @@ +#include +#include "gui/buttonswitch.h" + +ButtonSwitch::ButtonSwitch(QWidget* parent) : + QToolButton(parent) +{ + setCheckable(true); + m_originalPalette = palette(); + connect(this, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool))); +} + +void ButtonSwitch::onToggled(bool checked) +{ + if(checked) { + QPalette p = m_originalPalette; + p.setColor(QPalette::Button, QColor(0x80, 0x46, 0x00)); + setPalette(p); + } else { + setPalette(m_originalPalette); + } +} diff --git a/sdrbase/gui/channelwindow.cpp b/sdrbase/gui/channelwindow.cpp new file mode 100644 index 0000000..2849bf7 --- /dev/null +++ b/sdrbase/gui/channelwindow.cpp @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include "gui/channelwindow.h" +#include "gui/rollupwidget.h" + +ChannelWindow::ChannelWindow(QWidget* parent) : + QScrollArea(parent) +{ + m_container = new QWidget(this); + m_layout = new QBoxLayout(QBoxLayout::TopToBottom, m_container); + setWidget(m_container); + setWidgetResizable(true); + setBackgroundRole(QPalette::Base); + m_layout->setMargin(3); + m_layout->setSpacing(3); +} + +void ChannelWindow::addRollupWidget(QWidget* rollupWidget) +{ + rollupWidget->setParent(m_container); + m_container->layout()->addWidget(rollupWidget); +} + +void ChannelWindow::resizeEvent(QResizeEvent* event) +{ + if(event->size().height() > event->size().width()) { + m_layout->setDirection(QBoxLayout::TopToBottom); + m_layout->setAlignment(Qt::AlignTop); + } else { + m_layout->setDirection(QBoxLayout::LeftToRight); + m_layout->setAlignment(Qt::AlignLeft); + } + QScrollArea::resizeEvent(event); +} diff --git a/sdrbase/gui/glscope.cpp b/sdrbase/gui/glscope.cpp index 5f4ebb7..73c0d62 100644 --- a/sdrbase/gui/glscope.cpp +++ b/sdrbase/gui/glscope.cpp @@ -419,6 +419,22 @@ void GLScope::handleMode() } break; } + + case ModeCyclostationary: { + if(m_rawTrace.size() > 2) { + m_mathTrace.resize(m_rawTrace.size() - 2); + std::vector::iterator dst = m_mathTrace.begin(); + for(uint i = 2; i < m_rawTrace.size() ; i++) + *dst++ = Complex(abs(m_rawTrace[i] - conj(m_rawTrace[i - 1])), 0); + m_displayTrace = &m_mathTrace; + m_amp1 = m_amp; + m_amp2 = m_amp; + m_ofs1 = -1.0 / m_amp1; + m_ofs2 = 0.0; + } + break; + } + } } diff --git a/sdrbase/gui/glspectrum.cpp b/sdrbase/gui/glspectrum.cpp index 912d732..d9e33be 100644 --- a/sdrbase/gui/glspectrum.cpp +++ b/sdrbase/gui/glspectrum.cpp @@ -29,8 +29,7 @@ GLSpectrum::GLSpectrum(QWidget* parent) : m_sampleRate(500000), m_fftSize(512), m_invertedWaterfall(false), - m_displayLiveSpectrum(false), - m_liveSpectrumChanged(false), + m_displayMaxHold(false), m_leftMarginTextureAllocated(false), m_frequencyTextureAllocated(false), m_waterfallBuffer(NULL), @@ -51,7 +50,7 @@ GLSpectrum::GLSpectrum(QWidget* parent) : setMinimumSize(200, 200); - m_waterfallShare = 0.5; + m_waterfallShare = 0.66; for(int i = 0; i <= 239; i++) { QColor c; @@ -182,9 +181,9 @@ void GLSpectrum::setInvertedWaterfall(bool inv) update(); } -void GLSpectrum::setDisplayLiveSpectrum(bool display) +void GLSpectrum::setDisplayMaxHold(bool display) { - m_displayLiveSpectrum = display; + m_displayMaxHold = display; m_changesPending = true; stopDrag(); update(); @@ -245,11 +244,6 @@ void GLSpectrum::newSpectrum(const std::vector& spectrum, int fftSize) updateWaterfall(spectrum); updateHistogram(spectrum); - - if(!m_liveSpectrumChanged) { - std::copy(spectrum.begin(), spectrum.begin() + m_fftSize, m_liveSpectrum.begin()); - m_liveSpectrumChanged = true; - } } void GLSpectrum::updateWaterfall(const std::vector& spectrum) @@ -440,7 +434,7 @@ void GLSpectrum::paintGL() } // paint histogram - if(m_displayHistogram || m_displayLiveSpectrum) { + if(m_displayHistogram || m_displayMaxHold) { glPushMatrix(); glTranslatef(m_glHistogramRect.x(), m_glHistogramRect.y(), 0); glScalef(m_glHistogramRect.width(), m_glHistogramRect.height(), 1); @@ -522,7 +516,7 @@ void GLSpectrum::paintGL() } // paint left scales (time and power) - if(m_displayWaterfall || m_displayLiveSpectrum || m_displayHistogram ) { + if(m_displayWaterfall || m_displayMaxHold || m_displayHistogram ) { glBindTexture(GL_TEXTURE_2D, m_leftMarginTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -549,7 +543,7 @@ void GLSpectrum::paintGL() } // paint frequency scale - if(m_displayWaterfall || m_displayLiveSpectrum || m_displayHistogram ) { + if(m_displayWaterfall || m_displayMaxHold || m_displayHistogram ) { glBindTexture(GL_TEXTURE_2D, m_frequencyTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -575,10 +569,48 @@ void GLSpectrum::paintGL() glEnd(); glDisable(GL_TEXTURE_2D); glPopMatrix(); + + // paint channels + glPushMatrix(); + glTranslatef(m_glWaterfallRect.x(), m_glFrequencyScaleRect.y(), 0); + glScalef(m_glWaterfallRect.width(), m_glFrequencyScaleRect.height(), 1); + for(int i = 0; i < m_channelMarkerStates.size(); ++i) { + ChannelMarkerState* dv = m_channelMarkerStates[i]; + if(dv->m_channelMarker->getVisible()) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(dv->m_channelMarker->getColor().redF(), dv->m_channelMarker->getColor().greenF(), dv->m_channelMarker->getColor().blueF(), 0.3f); + glPushMatrix(); + glTranslatef(dv->m_glRect.x(), dv->m_glRect.y(), 0); + glScalef(dv->m_glRect.width(), dv->m_glRect.height(), 1); + glBegin(GL_QUADS); + glVertex2f(0, 0); + glVertex2f(1, 0); + glVertex2f(1, 1); + glVertex2f(0, 1); + glEnd(); + glDisable(GL_BLEND); + glPopMatrix(); + } + } + glPopMatrix(); } - // paint live spectrum lines on top of histogram - if(m_displayLiveSpectrum) { + // paint max hold lines on top of histogram + if(m_displayMaxHold) { + if(m_maxHold.size() < m_fftSize) + m_maxHold.resize(m_fftSize); + for(int i = 0; i < m_fftSize; i++) { + int j; + quint8* bs = m_histogram + i * 100; + for(j = 99; j > 0; j--) { + if(bs[j] > 0) + break; + } + j = j - 99; + m_maxHold[i] = (j * m_powerRange) / 99.0 + m_referenceLevel; + } + glPushMatrix(); glTranslatef(m_glHistogramRect.x(), m_glHistogramRect.y(), 0); glScalef(m_glHistogramRect.width() / (float)(m_fftSize - 1), -m_glHistogramRect.height() / m_powerRange, 1); @@ -586,11 +618,11 @@ void GLSpectrum::paintGL() glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LINE_SMOOTH); glLineWidth(1.0f); - glColor4f(1, 1, 1, 0.75f); + glColor3f(1, 0, 0); Real bottom = -m_powerRange; glBegin(GL_LINE_STRIP); for(int i = 0; i < m_fftSize; i++) { - Real v = m_liveSpectrum[i] - m_referenceLevel; + Real v = m_maxHold[i] - m_referenceLevel; if(v > 0) v = 0; else if(v < bottom) @@ -601,7 +633,6 @@ void GLSpectrum::paintGL() glDisable(GL_LINE_SMOOTH); glPopMatrix(); } - m_liveSpectrumChanged = false; // paint waterfall grid if(m_displayWaterfall) { @@ -649,7 +680,7 @@ void GLSpectrum::paintGL() } // paint histogram grid - if(m_displayHistogram || m_displayLiveSpectrum) { + if(m_displayHistogram || m_displayMaxHold) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glLineWidth(1.0f); @@ -718,8 +749,6 @@ void GLSpectrum::applyChanges() QFontMetrics fm(font()); int M = fm.width("-"); - m_liveSpectrum.resize(m_fftSize); - int topMargin = fm.ascent() * 1.5; int bottomMargin = fm.ascent() * 1.5; @@ -732,7 +761,7 @@ void GLSpectrum::applyChanges() int leftMargin; int rightMargin = fm.width("000"); - if(m_displayWaterfall && (m_displayHistogram | m_displayLiveSpectrum)) { + if(m_displayWaterfall && (m_displayHistogram | m_displayMaxHold)) { waterfallHeight = height() * m_waterfallShare - 1; if(waterfallHeight < 0) waterfallHeight = 0; @@ -848,7 +877,7 @@ void GLSpectrum::applyChanges() (float)(leftMargin - 1) / (float)width(), (float)1 ); - } else if(m_displayHistogram || m_displayLiveSpectrum) { + } else if(m_displayHistogram || m_displayMaxHold) { bottomMargin = frequencyScaleHeight; frequencyScaleTop = height() - bottomMargin; histogramTop = topMargin - 1; @@ -902,7 +931,7 @@ void GLSpectrum::applyChanges() 0, (dv->m_channelMarker->getBandwidth() / (float)m_sampleRate), 1); - if(m_displayHistogram || m_displayLiveSpectrum || m_displayWaterfall) { + if(m_displayHistogram || m_displayMaxHold || m_displayWaterfall) { dv->m_rect.setRect(m_frequencyScale.getPosFromValue(m_centerFrequency + dv->m_channelMarker->getCenterFrequency()) + leftMargin - 1, topMargin, 5, @@ -929,7 +958,7 @@ void GLSpectrum::applyChanges() } } } - if(m_displayHistogram || m_displayLiveSpectrum) { + if(m_displayHistogram || m_displayMaxHold) { tickList = &m_powerScale.getTickList(); for(int i = 0; i < tickList->count(); i++) { tick = &(*tickList)[i]; @@ -950,13 +979,14 @@ void GLSpectrum::applyChanges() m_leftMarginTextureAllocated = true; } // prepare frequency scale - if(m_displayWaterfall || m_displayHistogram || m_displayLiveSpectrum){ + if(m_displayWaterfall || m_displayHistogram || m_displayMaxHold){ m_frequencyPixmap = QPixmap(width(), frequencyScaleHeight); m_frequencyPixmap.fill(Qt::transparent); { QPainter painter(&m_frequencyPixmap); painter.setPen(Qt::NoPen); painter.setBrush(Qt::black); + painter.setBrush(Qt::transparent); painter.drawRect(leftMargin, 0, width() - leftMargin, frequencyScaleHeight); painter.setPen(QColor(0xf0, 0xf0, 0xff)); const ScaleEngine::TickList* tickList = &m_frequencyScale.getTickList(); @@ -1056,7 +1086,7 @@ void GLSpectrum::applyChanges() void GLSpectrum::mouseMoveEvent(QMouseEvent* event) { - if(m_displayWaterfall && (m_displayWaterfall || m_displayHistogram || m_displayLiveSpectrum)) { + if(m_displayWaterfall && (m_displayWaterfall || m_displayHistogram || m_displayMaxHold)) { if(m_frequencyScaleRect.contains(event->pos())) { if(m_cursorState == CSNormal) { setCursor(Qt::SizeVerCursor); @@ -1090,7 +1120,7 @@ void GLSpectrum::mouseMoveEvent(QMouseEvent* event) m_channelMarkerStates[m_cursorChannel]->m_channelMarker->setCenterFrequency(freq); } - if(m_displayWaterfall || m_displayHistogram || m_displayLiveSpectrum) { + if(m_displayWaterfall || m_displayHistogram || m_displayMaxHold) { for(int i = 0; i < m_channelMarkerStates.size(); ++i) { if(m_channelMarkerStates[i]->m_rect.contains(event->pos())) { if(m_cursorState == CSNormal) { diff --git a/sdrbase/gui/glspectrumgui.cpp b/sdrbase/gui/glspectrumgui.cpp index 6feaffd..52dd40d 100644 --- a/sdrbase/gui/glspectrumgui.cpp +++ b/sdrbase/gui/glspectrumgui.cpp @@ -2,8 +2,8 @@ #include "dsp/fftwindow.h" #include "dsp/spectrumvis.h" #include "gui/glspectrum.h" -#include "ui_glspectrumgui.h" #include "util/simpleserializer.h" +#include "ui_glspectrumgui.h" GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) : QWidget(parent), @@ -18,7 +18,7 @@ GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) : m_powerRange(100), m_displayWaterfall(true), m_invertedWaterfall(false), - m_displayLiveSpectrum(false), + m_displayMaxHold(false), m_displayHistogram(true) { ui->setupUi(this); @@ -46,7 +46,7 @@ void GLSpectrumGUI::resetToDefaults() m_powerRange = 100; m_displayWaterfall = true; m_invertedWaterfall = false; - m_displayLiveSpectrum = false; + m_displayMaxHold = false; m_displayHistogram = true; applySettings(); } @@ -61,7 +61,7 @@ QByteArray GLSpectrumGUI::serialize() const s.writeReal(5, m_powerRange); s.writeBool(6, m_displayWaterfall); s.writeBool(7, m_invertedWaterfall); - s.writeBool(8, m_displayLiveSpectrum); + s.writeBool(8, m_displayMaxHold); s.writeBool(9, m_displayHistogram); return s.final(); } @@ -83,7 +83,7 @@ bool GLSpectrumGUI::deserialize(const QByteArray& data) d.readReal(5, &m_powerRange, 100); d.readBool(6, &m_displayWaterfall, true); d.readBool(7, &m_invertedWaterfall, false); - d.readBool(8, &m_displayLiveSpectrum, false); + d.readBool(8, &m_displayMaxHold, false); d.readBool(9, &m_displayHistogram, true); applySettings(); return true; @@ -105,8 +105,8 @@ void GLSpectrumGUI::applySettings() ui->waterfall->setChecked(m_displayWaterfall); m_glSpectrum->setDisplayWaterfall(m_displayWaterfall); m_glSpectrum->setInvertedWaterfall(m_invertedWaterfall); - ui->liveSpectrum->setChecked(m_displayLiveSpectrum); - m_glSpectrum->setDisplayLiveSpectrum(m_displayLiveSpectrum); + ui->maxHold->setChecked(m_displayMaxHold); + m_glSpectrum->setDisplayMaxHold(m_displayMaxHold); ui->histogram->setChecked(m_displayHistogram); m_glSpectrum->setDisplayHistogram(m_displayHistogram); ui->refLevel->setValue((int)(m_refLevel / 10.0)); @@ -158,8 +158,8 @@ void GLSpectrumGUI::on_histogram_toggled(bool checked) m_glSpectrum->setDisplayHistogram(m_displayHistogram); } -void GLSpectrumGUI::on_liveSpectrum_toggled(bool checked) +void GLSpectrumGUI::on_maxHold_toggled(bool checked) { - m_displayLiveSpectrum = checked; - m_glSpectrum->setDisplayLiveSpectrum(m_displayLiveSpectrum); + m_displayMaxHold = checked; + m_glSpectrum->setDisplayMaxHold(m_displayMaxHold); } diff --git a/sdrbase/gui/glspectrumgui.ui b/sdrbase/gui/glspectrumgui.ui index 5c67ba6..048b3f6 100644 --- a/sdrbase/gui/glspectrumgui.ui +++ b/sdrbase/gui/glspectrumgui.ui @@ -7,7 +7,7 @@ 0 0 203 - 136 + 137 @@ -48,7 +48,7 @@ Qt::Horizontal - QSlider::TicksAbove + QSlider::TicksBelow 1 @@ -85,7 +85,7 @@ - + 24 @@ -144,7 +144,7 @@ Qt::Horizontal - QSlider::TicksAbove + QSlider::TicksBelow 1 @@ -174,7 +174,7 @@ - + 24 @@ -233,7 +233,7 @@ Qt::Horizontal - QSlider::TicksAbove + QSlider::TicksBelow 10 @@ -263,7 +263,7 @@ - + 24 @@ -278,7 +278,7 @@ - :/livespectrum.png:/livespectrum.png + :/maxhold.png:/maxhold.png @@ -390,7 +390,7 @@ Qt::Horizontal - QSlider::TicksAbove + QSlider::TicksBelow 1 @@ -401,6 +401,13 @@ + + + ButtonSwitch + QToolButton +
gui/buttonswitch.h
+
+
fftSize fftWindow @@ -409,7 +416,7 @@ decay waterfall histogram - liveSpectrum + maxHold diff --git a/sdrbase/gui/indicator.cpp b/sdrbase/gui/indicator.cpp index 184197d..d303578 100644 --- a/sdrbase/gui/indicator.cpp +++ b/sdrbase/gui/indicator.cpp @@ -42,6 +42,7 @@ Indicator::Indicator(const QString& text, QWidget* parent) : setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); QFont f = font(); + f.setBold(true); f.setPixelSize(8); setFont(f); } diff --git a/sdrbase/gui/preferencesdialog.ui b/sdrbase/gui/preferencesdialog.ui index 69f5d7d..0545931 100644 --- a/sdrbase/gui/preferencesdialog.ui +++ b/sdrbase/gui/preferencesdialog.ui @@ -17,7 +17,7 @@ - 1 + 0 diff --git a/sdrbase/gui/rollupwidget.cpp b/sdrbase/gui/rollupwidget.cpp new file mode 100644 index 0000000..010c88c --- /dev/null +++ b/sdrbase/gui/rollupwidget.cpp @@ -0,0 +1,231 @@ +#include +#include +#include +#include "gui/rollupwidget.h" +#include "ui_glspectrumgui.h" + +RollupWidget::RollupWidget(QWidget* parent) : + QWidget(parent) +{ + setMinimumSize(250, 150); + setMaximumSize(400, 200); + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + setBackgroundRole(QPalette::Window); + + setAutoFillBackground(false); + setAttribute(Qt::WA_OpaquePaintEvent, true); +} + +void RollupWidget::addRollup(QWidget* rollup) +{ + rollup->setParent(this); + installEventFilter(rollup); + arrangeRollups(); + repaint(); +} + +int RollupWidget::arrangeRollups() +{ + QFontMetrics fm(font()); + int pos = fm.height() + 4; + + for(int i = 0; i < children().count(); ++i) { + pos += fm.height() + 2; + QWidget* r = qobject_cast(children()[i]); + if(r != NULL) { + if(!r->isHidden()) { + r->move(2, pos + 3); + int h = 0; + if(r->hasHeightForWidth()) + h = r->heightForWidth(width() - 4); + else h = r->sizeHint().height(); + r->resize(width() - 4, h); + pos += r->height() + 5; + } + } + } + setMinimumHeight(pos); + setMaximumHeight(pos); + return pos; +} + +void RollupWidget::paintEvent(QPaintEvent*) +{ + QPainter p(this); + QColor frame = palette().highlight().color(); + + // Eigenbau + QFontMetrics fm(font()); + + p.setRenderHint(QPainter::Antialiasing, true); + + // Ecken + p.setPen(Qt::NoPen); + p.setBrush(palette().base()); + p.drawRect(0, 0, 5, 5); + p.drawRect(width() - 5, 0, 5, 5); + p.drawRect(0, height() - 5, 5, 5); + p.drawRect(width() - 5, height() - 5, 5, 5); + + // Rahmen + p.setPen(frame); + p.setBrush(palette().window()); + QRectF r(rect()); + r.adjust(0.5, 0.5, -0.5, -0.5); + p.drawRoundedRect(r, 3.0, 3.0, Qt::AbsoluteSize); + + // Titel-Hintergrund + p.setPen(Qt::NoPen); + p.setBrush(palette().highlight()); + QPainterPath path; + path.moveTo(1.5, fm.height() + 2.5); + path.lineTo(width() - 1.5, fm.height() + 2.5); + path.lineTo(width() - 1.5, 3.5); + path.arcTo(QRectF(width() - 3.5, 0, 2.5, 2.5), 270, -90); + path.lineTo(3.5, 1.5); + path.arcTo(QRectF(1.5, 2.5, 2.5, 2.5), 90, 90); + p.drawPath(path); + + // Titel-Abschlusslinie + p.setPen(frame); + p.drawLine(QPointF(0.5, 2 + fm.height() + 1.5), QPointF(width() - 1.5, 2 + fm.height() + 1.5)); + + // Aktiv-Button links + p.setPen(QPen(palette().windowText().color(), 1.0)); + p.setBrush(palette().light()); + p.drawRoundedRect(QRectF(3.5, 3.5, fm.ascent(), fm.ascent()), 2.0, 2.0, Qt::AbsoluteSize); + + // Schließen-Button rechts + p.setRenderHint(QPainter::Antialiasing, true); + p.setPen(QPen(palette().windowText().color(), 1.0)); + p.setBrush(palette().light()); + r = QRectF(width() - 3.5 - fm.ascent(), 3.5, fm.ascent(), fm.ascent()); + p.drawRoundedRect(r, 2.0, 2.0, Qt::AbsoluteSize); + p.setPen(QPen(palette().windowText().color(), 1.5)); + p.drawLine(r.topLeft() + QPointF(1, 1), r.bottomRight() + QPointF(-1, -1)); + p.drawLine(r.bottomLeft() + QPointF(1, -1), r.topRight() + QPointF(-1, 1)); + + // Titel + p.setPen(palette().highlightedText().color()); + p.drawText(QRect(2 + fm.height(), 2, width() - 4 - 2 * fm.height(), fm.height()), + fm.elidedText(windowTitle(), Qt::ElideMiddle, width() - 4 - 2 * fm.height(), 0)); + + // Rollups + int pos = fm.height() + 4; + for(int i = 0; i < children().count(); ++i) { + QWidget* r = qobject_cast(children()[i]); + if(r != NULL) + pos += paintRollup(r, pos, &p, i == children().count() - 1, frame); + } +} + +int RollupWidget::paintRollup(QWidget* rollup, int pos, QPainter* p, bool last, const QColor& frame) +{ + QFontMetrics fm(font()); + int height = 1; + + // Titel-Abschlusslinie + if(!rollup->isHidden()) { + p->setPen(palette().dark().color()); + p->drawLine(QPointF(1.5, pos + fm.height() + 1.5), QPointF(width() - 1.5, pos + fm.height() + 1.5)); + p->setPen(palette().light().color()); + p->drawLine(QPointF(1.5, pos + fm.height() + 2.5), QPointF(width() - 1.5, pos + fm.height() + 2.5)); + height += 2; + } else { + if(!last) { + p->setPen(frame); + p->drawLine(QPointF(1.5, pos + fm.height() + 1.5), QPointF(width() - 1.5, pos + fm.height() + 1.5)); + height++; + } + } + + // Titel + p->setPen(palette().windowText().color()); + p->drawText(QRect(2 + fm.height(), pos, width() - 4 - fm.height(), fm.height()), + fm.elidedText(rollup->windowTitle(), Qt::ElideMiddle, width() - 4 - fm.height(), 0)); + height += fm.height(); + + // Ausklapp-Icon + p->setPen(palette().windowText().color()); + p->setBrush(palette().windowText()); + if(!rollup->isHidden()) { + QPolygonF a; + a.append(QPointF(3.5, pos + 2)); + a.append(QPointF(3.5 + fm.ascent(), pos + 2)); + a.append(QPointF(3.5 + fm.ascent() / 2.0, pos + fm.height() - 2)); + p->drawPolygon(a); + } else { + QPolygonF a; + a.append(QPointF(3.5, pos + 2)); + a.append(QPointF(3.5, pos + fm.height() - 2)); + a.append(QPointF(3.5 + fm.ascent(), pos + fm.height() / 2)); + p->drawPolygon(a); + } + + // Inhalt + if(!rollup->isHidden() && (!last)) { + // Rollup-Abschlusslinie + p->setPen(frame); + p->drawLine(QPointF(1.5, pos + fm.height() + rollup->height() + 6.5), + QPointF(width() - 1.5, pos + fm.height() + rollup->height() + 6.5)); + height += rollup->height() + 4; + } + + return height; +} + +void RollupWidget::resizeEvent(QResizeEvent* size) +{ + arrangeRollups(); + QWidget::resizeEvent(size); +} + +void RollupWidget::mousePressEvent(QMouseEvent* event) +{ + QFontMetrics fm(font()); + + // menu box left + if(QRectF(3.5, 3.5, fm.ascent(), fm.ascent()).contains(event->pos())) { + emit customContextMenuRequested(event->pos()); + return; + } + + // close button right + if(QRectF(width() - 3.5 - fm.ascent(), 3.5, fm.ascent(), fm.ascent()).contains(event->pos())) { + close(); + return; + } + + // check if we need to change a rollup widget + int pos = fm.height() + 4; + for(int i = 0; i < children().count(); ++i) { + QWidget* r = qobject_cast(children()[i]); + if(r != NULL) { + if((event->y() >= pos) && (event->y() < (pos + fm.height() + 3))) { + if(r->isHidden()) + r->show(); + else r->hide(); + arrangeRollups(); + repaint(); + return; + } else { + pos += fm.height() + 2; + if(!r->isHidden()) + pos += r->height() + 5; + } + } + } +} + +bool RollupWidget::eventFilter(QObject* object, QEvent* event) +{ + if((event->type() == QEvent::Show) || (event->type() == QEvent::Hide)) { + if(children().contains(object)) + arrangeRollups(); + } else if((event->type() == QEvent::ChildAdded) || (event->type() == QEvent::ChildRemoved)) { + if(children().contains(object)) + arrangeRollups(); + } + + return QWidget::eventFilter(object, event); +} diff --git a/sdrbase/gui/scopewindow.cpp b/sdrbase/gui/scopewindow.cpp index 6188b64..2f6200f 100644 --- a/sdrbase/gui/scopewindow.cpp +++ b/sdrbase/gui/scopewindow.cpp @@ -135,6 +135,10 @@ void ScopeWindow::on_displayMode_currentIndexChanged(int index) case 3: // derived1+derived2 ui->scope->setMode(GLScope::ModeDerived12); break; + case 4: // clostationary + ui->scope->setMode(GLScope::ModeCyclostationary); + break; + default: break; } diff --git a/sdrbase/gui/scopewindow.ui b/sdrbase/gui/scopewindow.ui index a2c7ffd..d521af3 100644 --- a/sdrbase/gui/scopewindow.ui +++ b/sdrbase/gui/scopewindow.ui @@ -82,6 +82,11 @@ Derived 1st + 2nd order
+ + + Cyclostationary + + diff --git a/sdrbase/mainwindow.cpp b/sdrbase/mainwindow.cpp index 46feac6..370633c 100644 --- a/sdrbase/mainwindow.cpp +++ b/sdrbase/mainwindow.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include "mainwindow.h" #include "ui_mainwindow.h" @@ -29,6 +28,7 @@ #include "gui/pluginsdialog.h" #include "gui/preferencesdialog.h" #include "gui/aboutdialog.h" +#include "gui/rollupwidget.h" #include "dsp/dspengine.h" #include "dsp/spectrumvis.h" #include "dsp/dspcommands.h" @@ -59,20 +59,25 @@ MainWindow::MainWindow(QWidget* parent) : setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); + // work around broken Qt dock widget ordering removeDockWidget(ui->inputDock); removeDockWidget(ui->processingDock); removeDockWidget(ui->presetDock); + removeDockWidget(ui->channelDock); addDockWidget(Qt::LeftDockWidgetArea, ui->inputDock); addDockWidget(Qt::LeftDockWidgetArea, ui->processingDock); addDockWidget(Qt::LeftDockWidgetArea, ui->presetDock); + addDockWidget(Qt::RightDockWidgetArea, ui->channelDock); ui->inputDock->show(); ui->processingDock->show(); ui->presetDock->show(); + ui->channelDock->show(); ui->menu_Window->addAction(ui->inputDock->toggleViewAction()); ui->menu_Window->addAction(ui->processingDock->toggleViewAction()); ui->menu_Window->addAction(ui->presetDock->toggleViewAction()); + ui->menu_Window->addAction(ui->channelDock->toggleViewAction()); connect(m_messageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleMessages()), Qt::QueuedConnection); @@ -131,9 +136,14 @@ MainWindow::~MainWindow() delete ui; } -void MainWindow::addDemodCreateAction(QAction* action) +void MainWindow::addChannelCreateAction(QAction* action) { - ui->menu_Demodulation->addAction(action); + ui->menu_Channels->addAction(action); +} + +void MainWindow::addChannelRollup(QWidget* widget) +{ + ((ChannelWindow*)ui->channelDock->widget())->addRollupWidget(widget); } void MainWindow::addViewAction(QAction* action) @@ -201,7 +211,7 @@ void MainWindow::saveSettings(Preset* preset) preset->setScopeConfig(m_scopeWindow->serialize()); else preset->setScopeConfig(QByteArray()); - preset->clearDemods(); + preset->clearChannels(); m_pluginManager->saveSettings(preset); preset->setLayout(saveState()); @@ -502,7 +512,6 @@ void MainWindow::on_action_Preferences_triggered() preferencesDialog.exec(); } - void MainWindow::on_sampleSource_currentIndexChanged(int index) { m_pluginManager->selectSampleSource(ui->sampleSource->currentIndex()); diff --git a/sdrbase/mainwindow.ui b/sdrbase/mainwindow.ui index 2527bfa..d9299de 100644 --- a/sdrbase/mainwindow.ui +++ b/sdrbase/mainwindow.ui @@ -22,16 +22,7 @@ - - 0 - - - 0 - - - 0 - - + 0 @@ -52,7 +43,7 @@ 0 0 1012 - 24 + 23 @@ -95,9 +86,9 @@ - + - &Demodulation + &Channels @@ -108,7 +99,7 @@ - + @@ -131,16 +122,7 @@ - - 2 - - - 2 - - - 2 - - + 2 @@ -257,16 +239,7 @@ 3 - - 2 - - - 2 - - - 2 - - + 2 @@ -275,7 +248,7 @@ 3 - + 0 @@ -288,13 +261,10 @@ DC Offset Corr - - true - - + 0 @@ -307,9 +277,6 @@ I/Q Imbal. Corr - - true - @@ -338,16 +305,7 @@ 3 - - 2 - - - 2 - - - 2 - - + 2 @@ -360,6 +318,24 @@ + + + Channels + + + 2 + + + + + 3 + + + 2 + + + + E&xit @@ -447,6 +423,7 @@ presetDock + channelDock @@ -462,6 +439,17 @@
gui/glspectrumgui.h
1 + + ButtonSwitch + QToolButton +
gui/buttonswitch.h
+
+ + ChannelWindow + QWidget +
gui/channelwindow.h
+ 1 +
presetTree diff --git a/sdrbase/plugin/pluginapi.cpp b/sdrbase/plugin/pluginapi.cpp index d1059fe..b3a842d 100644 --- a/sdrbase/plugin/pluginapi.cpp +++ b/sdrbase/plugin/pluginapi.cpp @@ -19,14 +19,29 @@ MessageQueue* PluginAPI::getMainWindowMessageQueue() return m_mainWindow->getMessageQueue(); } -void PluginAPI::registerDemodulator(const QString& demodName, PluginInterface* plugin, QAction* action) +void PluginAPI::setInputGUI(QWidget* inputGUI) { - m_pluginManager->registerDemodulator(demodName, plugin, action); + m_mainWindow->setInputGUI(inputGUI); } -void PluginAPI::registerDemodulatorInstance(const QString& demodName, PluginGUI* pluginGUI) +void PluginAPI::registerChannel(const QString& channelName, PluginInterface* plugin, QAction* action) { - m_pluginManager->registerDemodulatorInstance(demodName, pluginGUI); + m_pluginManager->registerChannel(channelName, plugin, action); +} + +void PluginAPI::registerChannelInstance(const QString& channelName, PluginGUI* pluginGUI) +{ + m_pluginManager->registerChannelInstance(channelName, pluginGUI); +} + +void PluginAPI::addChannelRollup(QWidget* pluginGUI) +{ + m_pluginManager->addChannelRollup(pluginGUI); +} + +void PluginAPI::removeChannelInstance(PluginGUI* pluginGUI) +{ + m_pluginManager->removeChannelInstance(pluginGUI); } void PluginAPI::addChannelMarker(ChannelMarker* channelMarker) diff --git a/sdrbase/plugin/plugingui.cpp b/sdrbase/plugin/plugingui.cpp index a678da3..63ddcce 100644 --- a/sdrbase/plugin/plugingui.cpp +++ b/sdrbase/plugin/plugingui.cpp @@ -1,15 +1,5 @@ #include "plugin/plugingui.h" -PluginGUI::PluginGUI(QWidget* parent) : - QWidget(parent) -{ -} - -void PluginGUI::setWidgetName(const QString& name) -{ - setObjectName(name); -} - QByteArray PluginGUI::serializeGeneral() const { return QByteArray(); diff --git a/sdrbase/plugin/pluginmanager.cpp b/sdrbase/plugin/pluginmanager.cpp index 7a5f699..b2aeb6e 100644 --- a/sdrbase/plugin/pluginmanager.cpp +++ b/sdrbase/plugin/pluginmanager.cpp @@ -37,17 +37,32 @@ void PluginManager::loadPlugins() updateSampleSourceDevices(); } -void PluginManager::registerDemodulator(const QString& demodName, PluginInterface* plugin, QAction* action) +void PluginManager::registerChannel(const QString& channelName, PluginInterface* plugin, QAction* action) { - m_demodRegistrations.append(DemodRegistration(demodName, plugin)); - m_mainWindow->addDemodCreateAction(action); + m_channelRegistrations.append(ChannelRegistration(channelName, plugin)); + m_mainWindow->addChannelCreateAction(action); } -void PluginManager::registerDemodulatorInstance(const QString& demodName, PluginGUI* pluginGUI) +void PluginManager::registerChannelInstance(const QString& channelName, PluginGUI* pluginGUI) { - connect(pluginGUI, SIGNAL(destroyed(QObject*)), this, SLOT(demodInstanceDestroyed(QObject*))); - m_demodInstanceRegistrations.append(DemodInstanceRegistration(demodName, pluginGUI)); - renameDemodInstances(); + m_channelInstanceRegistrations.append(ChannelInstanceRegistration(channelName, pluginGUI)); + renameChannelInstances(); +} + +void PluginManager::addChannelRollup(QWidget* pluginGUI) +{ + m_mainWindow->addChannelRollup(pluginGUI); +} + +void PluginManager::removeChannelInstance(PluginGUI* pluginGUI) +{ + for(ChannelInstanceRegistrations::iterator it = m_channelInstanceRegistrations.begin(); it != m_channelInstanceRegistrations.end(); ++it) { + if(it->m_gui == pluginGUI) { + m_channelInstanceRegistrations.erase(it); + break; + } + } + renameChannelInstances(); } void PluginManager::registerSampleSource(const QString& sourceName, PluginInterface* plugin) @@ -59,46 +74,44 @@ void PluginManager::loadSettings(const Preset* preset) { qDebug("-------- [%s | %s] --------", qPrintable(preset->getGroup()), qPrintable(preset->getDescription())); - // copy currently open demods and clear list - DemodInstanceRegistrations availableDemods = m_demodInstanceRegistrations; - m_demodInstanceRegistrations.clear(); + // copy currently open channels and clear list + ChannelInstanceRegistrations openChannels = m_channelInstanceRegistrations; + m_channelInstanceRegistrations.clear(); - for(int i = 0; i < preset->getDemodCount(); i++) { - const Preset::DemodConfig& demodConfig = preset->getDemodConfig(i); - DemodInstanceRegistration reg; + for(int i = 0; i < preset->getChannelCount(); i++) { + const Preset::ChannelConfig& channelConfig = preset->getChannelConfig(i); + ChannelInstanceRegistration reg; // if we have one instance available already, use it - for(int i = 0; i < availableDemods.count(); i++) { - qDebug("compare [%s] vs [%s]", qPrintable(availableDemods[i].m_demodName), qPrintable(demodConfig.m_demod)); - if(availableDemods[i].m_demodName == demodConfig.m_demod) { - qDebug("demod [%s] found", qPrintable(availableDemods[i].m_demodName)); - reg = availableDemods.takeAt(i); - m_demodInstanceRegistrations.append(reg); + for(int i = 0; i < openChannels.count(); i++) { + qDebug("compare [%s] vs [%s]", qPrintable(openChannels[i].m_channelName), qPrintable(channelConfig.m_channel)); + if(openChannels[i].m_channelName == channelConfig.m_channel) { + qDebug("channel [%s] found", qPrintable(openChannels[i].m_channelName)); + reg = openChannels.takeAt(i); + m_channelInstanceRegistrations.append(reg); break; } } // if we haven't one already, create one if(reg.m_gui == NULL) { - for(int i = 0; i < m_demodRegistrations.count(); i++) { - if(m_demodRegistrations[i].m_demodName == demodConfig.m_demod) { - qDebug("creating new demod [%s]", qPrintable(demodConfig.m_demod)); - reg = DemodInstanceRegistration(demodConfig.m_demod, m_demodRegistrations[i].m_plugin->createDemod(demodConfig.m_demod)); + for(int i = 0; i < m_channelRegistrations.count(); i++) { + if(m_channelRegistrations[i].m_channelName == channelConfig.m_channel) { + qDebug("creating new channel [%s]", qPrintable(channelConfig.m_channel)); + reg = ChannelInstanceRegistration(channelConfig.m_channel, m_channelRegistrations[i].m_plugin->createChannel(channelConfig.m_channel)); break; } } } - if(reg.m_gui != NULL) { - reg.m_gui->deserialize(demodConfig.m_config); - reg.m_gui->raise(); - } + if(reg.m_gui != NULL) + reg.m_gui->deserialize(channelConfig.m_config); } // everything, that is still "available" is not needed anymore - for(int i = 0; i < availableDemods.count(); i++) { - qDebug("destroying spare demod [%s]", qPrintable(availableDemods[i].m_demodName)); - availableDemods[i].m_gui->destroy(); + for(int i = 0; i < openChannels.count(); i++) { + qDebug("destroying spare channel [%s]", qPrintable(openChannels[i].m_channelName)); + openChannels[i].m_gui->destroy(); } - renameDemodInstances(); + renameChannelInstances(); if(m_sampleSourceInstance != NULL) { m_sampleSourceInstance->deserializeGeneral(preset->getSourceGeneralConfig()); @@ -116,17 +129,16 @@ void PluginManager::saveSettings(Preset* preset) const } else { preset->setSourceConfig(QString::null, QByteArray(), QByteArray()); } - for(int i = 0; i < m_demodInstanceRegistrations.size(); i++) - preset->addDemod(m_demodInstanceRegistrations[i].m_demodName, m_demodInstanceRegistrations[i].m_gui->serialize()); + for(int i = 0; i < m_channelInstanceRegistrations.count(); i++) + preset->addChannel(m_channelInstanceRegistrations[i].m_channelName, m_channelInstanceRegistrations[i].m_gui->serialize()); } void PluginManager::freeAll() { m_dspEngine->stopAcquistion(); - while(!m_demodInstanceRegistrations.isEmpty()) { - DemodInstanceRegistration reg(m_demodInstanceRegistrations.takeLast()); - reg.m_gui->disconnect(this); + while(!m_channelInstanceRegistrations.isEmpty()) { + ChannelInstanceRegistration reg(m_channelInstanceRegistrations.takeLast()); reg.m_gui->destroy(); } @@ -147,7 +159,7 @@ bool PluginManager::handleMessage(Message* message) } } - for(DemodInstanceRegistrations::iterator it = m_demodInstanceRegistrations.begin(); it != m_demodInstanceRegistrations.end(); ++it) { + for(ChannelInstanceRegistrations::iterator it = m_channelInstanceRegistrations.begin(); it != m_channelInstanceRegistrations.end(); ++it) { if((message->destination() == NULL) || (message->destination() == it->m_gui)) { if(it->m_gui->handleMessage(message)) return true; @@ -204,7 +216,6 @@ int PluginManager::selectSampleSource(int index) m_sampleSource = m_sampleSourceDevices[index].m_sourceName; m_sampleSourceInstance = m_sampleSourceDevices[index].m_plugin->createSampleSource(m_sampleSource, m_sampleSourceDevices[index].m_address); - m_mainWindow->setInputGUI(m_sampleSourceInstance); return index; } @@ -239,21 +250,9 @@ int PluginManager::selectSampleSource(const QString& source) m_sampleSource = m_sampleSourceDevices[index].m_sourceName; m_sampleSourceInstance = m_sampleSourceDevices[index].m_plugin->createSampleSource(m_sampleSource, m_sampleSourceDevices[index].m_address); - m_mainWindow->setInputGUI(m_sampleSourceInstance); return index; } -void PluginManager::demodInstanceDestroyed(QObject* object) -{ - for(DemodInstanceRegistrations::iterator it = m_demodInstanceRegistrations.begin(); it != m_demodInstanceRegistrations.end(); ++it) { - if(it->m_gui == object) { - m_demodInstanceRegistrations.erase(it); - break; - } - } - renameDemodInstances(); -} - void PluginManager::loadPlugins(const QDir& dir) { QDir pluginsDir(dir); @@ -273,9 +272,9 @@ void PluginManager::loadPlugins(const QDir& dir) loadPlugins(pluginsDir.absoluteFilePath(dirName)); } -void PluginManager::renameDemodInstances() +void PluginManager::renameChannelInstances() { - for(int i = 0; i < m_demodInstanceRegistrations.count(); i++) { - m_demodInstanceRegistrations[i].m_gui->setWidgetName(QString("%1:%2").arg(m_demodInstanceRegistrations[i].m_demodName).arg(i)); + for(int i = 0; i < m_channelInstanceRegistrations.count(); i++) { + m_channelInstanceRegistrations[i].m_gui->setName(QString("%1:%2").arg(m_channelInstanceRegistrations[i].m_channelName).arg(i)); } } diff --git a/sdrbase/resources/histogram.png b/sdrbase/resources/histogram.png index 673f2fa164aebf2f3bfb26471069c25b9b628fdf..48bf143e77bce0dbe99722742e98bb465c190bda 100644 GIT binary patch delta 1150 zcmV-^1cCe13Wy1i8Gix*003_ls;>Y5010qNS#tmY3ljhU3ljkVnw%H_000McNliru z-3bo~Bpx#{FgySN1Sd&EK~y-)m6S_tRAm&$|KH<2=gxad$7!i8)bdh+286OO#3&nM za3KrW2nk5S#<*hd!ljzH*B!>hL{@|ljk;2!5G?^8j0jC%(|>t&X71d%kMH4vL~1i7 zdY0!Tzx>bdB!>W5Y+0HRg8)h=0KpTB0rt>=V>;f*(PI~OI=lBag456CowZi=2_ViG z8#<6iZhhwb+@UKI`+vRo$C=g63a8M7Z3)_9C&khgKFQzz@vKx9+Y!kJyBxy^gxqRJ zE~OmS7lq2~l7C_70>M2ZT@rGS+hy5V*a}34<}vN3nx$FTz<^*~pcV(hw9CiH|B_9B zvFVe|{5~`UT?x^b+GAA60Ugcwcf)XfXs98HT(43~9nGHXT{?3`63g9<4=%lT;Pe-g z=2KH|c&7cI5-~!YiC6lg2R(Noan$0?vG_02VCwhZ4u2)W)ym5U_xzx#hk>k(cD%wf zy308sG&54c zu5+^Fpp&2$g8~VrlV8&H8x#Tx&_FYR$6CeXM&SUbYzWApJiF&?L|kZvNTDN;Xd6+p z*IcU2&xG?xfWAPYFi@H!$j%yu1L%z)1tht`j(=`$28KecVKXQVLU{XDt#Mmx-3|v9 zLP&rTP=KN9?ab$%{+I0S(Coa}G4b3c48bl#cAb=)$-SYd(;lP(l5F|#lB+We-NSG8- zfq#%C?{K-?Y*w#pXaLMUd`@g9yHDMw6uMY317#*)+?)x%lEI&fXu~ixQF-xz6%SJG zn4FldVR~E}PT)?Cn9^43j8i`M*42yk`C~2Fn{6HW@^ZIbMj%RJDQ-VpYc)d=5&~%A z`@y!{d@DT%MbU}j8t6&5#cuIb#y!IN_ka1dmFwnWE*xKdXY_^c(hQO|H1)!2t+N=! z!K44FwYE4%@Q{0l1T6TAr z)sT(v{q9065=tomrBoy$DdSwa5*Q^I#I1G8O_(7P{{+VrM^pf=w7Y0cRSrTW!uHNU+yvM^!wF5j^)n^&2iJ&QO&C;$S5 zwCbfgH|x!NK^y?&Q6jB10LQRArdzq=Y2^>P#C?vGtN_wN;9!rCRZdzDN;$5m6sRMG!&I2VcY&9|Z+P6cMprtAYr%f>pG& zMw?ztQj_UqCNpy~bI#dk`!H={ip~%J!(Mysz4lt`Ut2)8rhf^9Fpv_IQZ$F)?j84V z;P9uEYYWR()3%+a$4pZqr635J1&GOJ*D*i3hrawGQ&R_t7=I6`W>RRx@}B9s?y5{3CqwODO_EX|glyVmDH90GAkk-nnV{x*#Hvwx z)A#*VWf<^0j$LFkjOGC_EUcu5Iw+}2hq$KDp?{$Vs}W#bBvbicZmZyVU65;o*$CB| z;);>&K-9>>vK?JeJcalIudCSF3S|0g?O;;S#+ck3DVP#VP9}z0u2?a$> z7*Nr~iGKth4RuN(KnTH-k-;!PZ3*y=j^*-LriJINSzcdE3zI0Ffd~fcrG`)pgLHbJ zF=#0(Nz%*VCR0ca#;Ftue1tI2TG79LH}0O-Xt6D%0z+z+hO!4I@Na zpt`T6#qp5CT^leuH<7#i5yDWT+XK4RtV8P>u7B5sKX3zQySu396iO+S3YUpi6bA1^ zX8{AUK>;IBXiHP*+R4zC`;ccQo@4KAH}Ol)WzcC77BzowxEJ*sdqp!zX;XF3DrLpLpQXeO!~Nv#@Z6M9&0s{X1!kL(2P1%!)||A*LDQCM0ed zyoZWx{=60Qt-aqe;Gf|BHA&uAV|?(NNpft7A7(Z&)Z5J^BU7Zd9HP>G6{p)Dq*ygj zwoRyEIySJ@MufjBDEb^Z{u7zejrjR2et$YedruyDZ}m+EN@cdse8%U;T2VUW_3dxN zB@XY_yLrO?h8GV%$V>Ys$+j4j9S1*U5{`hoSumVC2PXv`(K$}epTMXU5G6&gmW<`* zF$-y!HeHTnZ{+8GL0`=sPpT zerG?-38t%8aF_WW_pV(;;v?qs5S7Wyn52seYG;XrqUslDwO}p}pA2rq$Y&pYzVw$Q zToQ!7B60QtOJ+uj9Ho!do zG5Li*@uDS)-Mjg<-op2jt(YjtR7xyZ>BeX;PD5!Mw;#9_r+g`*6kw)e-uh^m4=*2p z@*UK)MYxdUjlW0XbjUW9XS#H{@u@^LhSdT`OF7IX9}_7EwE_WS{v5MG2}R-H*H2Ia4;SmVGISO8Ydo+wCkWrSNz>07xnS zlT35D9O-nLY&J_zPY)kIek?<+WipvEhf+;S|7rndW@fM~i>aw8LZJ}v-n}bFP>rH$ zHatAc$jAsvDK1{Tc$6Yt*PTJ3P{1$@N1i1F#}!*CMPp+l-@kvSrltmfj*bon1_p>m zqmH7q!y5Pd{SLRKgDO!J3WX3tkk9AI<#Md7tkB!r%a0#FuqZXFw7cXyXqEJjUD4N56&+orp_o6XHlo<4ob=;$b-udk15*RCO@#4rrv z@i^gd7+u%7di5&p?d`O*v>=2)*L8GVN7FPs9uM{P^(-wd5sgOK+}s49wzih(>1o>9 z+VK1RXlKu!Wn^T8y1F`k{rbh{&z~_(lShvpv9`9x>({TjeEBj`N=k~mapMM;E?puR z3^F-6Sw?56bzHb`flMZYsIRX_*L7~*yoqU=)YjHIoIig2m?ux3(An9^!-o$6xOeX! zrfD)dI*Q-#CzVP$0$5sF!Y~YcJ|9XcdV6~jdwY8X0s&H~6q=^ta=F;v-e!4u87U=+ zM1o?mNLN=EK@!)c~`10iohGF1#yOB~NrDSk$5U({T2 z-Vb)tbUMw>&JM9y43W)dNhA^+>`B>dmihU4*4Nh&LJ$szdGX=}6B85U^Lci6cZozI zM~YjrY&J_Q7TdoEdwYB6x=u72WoKsxAq3yPeJg{%v9WFMAo>xpU{(S4Cf6pZ)&*dwX$l(GCWK6<-zOho<4n=4kdn00000 LNkvXXu0mjfp&1dK diff --git a/sdrbase/resources/maxhold.png b/sdrbase/resources/maxhold.png new file mode 100644 index 0000000000000000000000000000000000000000..edabbd8a8291126cc8177ee49b07bd6b7fa31b79 GIT binary patch literal 594 zcmV-Y0F@mF$5nhPWte_T^b3zZ5gRBIPOMChNO^pDU%L=aq@x;b^};?O}C z2caOSldGGh4nm=5O9pE}TB?=QV$wK-E0?N?$!EIf`#ksNd7gWo?~zcJDaJ@?Q?XdA zR4O_uoiwho#2TND1f|ouDKkDk-g+uC&pdB@az39A!!QVfu0&(hz!X&` z+e?e0sE5*8#uh8w?yk6(sWQ?xD2PG$!twq|!dF`xj_vXb2G{HW_7~lLQnvMV(@)^faFj>-Dpl%wFg35V4mqr>Rni&0B>+ zHHy|)=-Q(ri}aISF2&}>AlOc)Uoi2XD{`nG>?GDLLzbZ9l&1eWIN#agG8kr*6;`QH z=?V0ek6ZyaxWIj0fxC&Y6Wn7s2^wo}c8%ru0=P+yD(f6@JrVYRN4#X>5OjyP?Wr~> z@tR2V8IhIgFiaqFEq_WvmUJWH&$uFAw;KXPYZ gO4OM<+Rjq>lD*ylh07*qoM6N<$f?{U>GXMYp literal 0 HcmV?d00001 diff --git a/sdrbase/resources/res.qrc b/sdrbase/resources/res.qrc index 9e348a1..0d2ecd6 100644 --- a/sdrbase/resources/res.qrc +++ b/sdrbase/resources/res.qrc @@ -2,7 +2,6 @@ appicon.png histogram.png - livespectrum.png waterfall.png preset-load.png preset-save.png @@ -10,5 +9,6 @@ horizontal.png vertical.png logo.png + maxhold.png diff --git a/sdrbase/resources/waterfall.png b/sdrbase/resources/waterfall.png index 9b2b72751da03d7bbc510c0200a5415f05f412d7..9e520906ef20fec2ba0d96487a7ab85cb2dd6887 100644 GIT binary patch delta 1360 zcmV-W1+V(j3fKye8Gix*003_ls;>Y5010qNS#tmY3ljhU3ljkVnw%H_000McNliru z-3bo~4=QB!Ip6>Q1oufqK~y-)CD6%kV_5-!;r|SGuzd#)aU5qT2u)RWLl=Tl_Xddt zErA3pUV;TY2k(Kzf*oswgpiOBLJeYp8YoDol2m23`D^h`2e%O6m&j z>1@4X|DHUN{y!(<%X!C3q%9ir^$z_FrPn!MXMM$G&bnbTn%{0Imo;pJMG70p*?&4}cKwYt&QTZ|iE2a~P&*QhXS!Jtn(c_*j&Mg6U^PxNx3ogyS0bL_ z=R%udnzMo}jq>{6s9S|Ti2f>Qjq;(tS_cz(((@06&Fj-+7#uI)O_)S}f*H!D_wq_Nx zXZZU$%a+r~9;Mq<1p6oF-r!LrkAwxTM@LX-#YZmy>Mrq;%c9oPde@nk@^4>$<@t1e zE23Ym^M7CXe51!7NZv&O3l!3$>oHP<9y$nUh9arsT2uFgYMjzKJA;17x}Yl=%vglNuTS^qPbCK-bsN0N zvLAIYH5WBkJ9@A-S)^rcY&O?S-mo1Y2b!ej=$=-i2oBFNV(j_f?(^pvrxATme3~*Y zF@GIyn&5R>y)Q|8UJvcrT0T&cPk21UXpIY4?o(-QM0K~vAX^b+cKl|h;e;#vH^0N{C zf?s-UHn9@?`ip&6C0|}o^Z%TZ%*<}gJ%1=G=~e_KenD@66QoOw7p9Ask*h3wiouL> zM6Ng;=2tt6Y!Qa-fRlTKVRisRodjj*j~eXo&lmLnZbQdtB@0Zs)3t*nri zXoKG%KsQV@fshz!s?cI+{B<5;<>iL0;cH#qhRDXf_L$eCid2b*MbxZE1Ucb`-ilhV z^>{EKbP~p>G4TUP9e0P_dYzpVVt@4_5&tOpUXmQwJE!Ocd^~06)HE&L-{S5*MqBy; zh2lV=t;`=jjNv5aiTKcpAr&`!anp#q zC?0cNTibS}i}Frf?!+pHLoYCJo^kA0G^COJg7slK8%IOL?ue1TXBfzlCFGIowafVn z^YoyJ8OO+G8ZWDFm-M(TnIF{o+;CTM9+*ciDs`0z^?!<24QDgbVrmcvlHAZ^}rsH-6vMQJ6xo|Znq?9TB$YxJfFf45QrLXd}JOuew ziJYdB#ex_I4CFxW@Lp2XPZQG#}XifNa)s{*#MrYaM&L{iSY$`;O)) z*mTqQUEn{_(5|@JPGqf*q=_L(>Ea~GeMi$xE`Q%1Y4G}U&->nId9OJ8p7RrFpc`fN zbxk_Zr^MdUlKh4;a2C0$)r(Z9<~&L#AdW4UGmaxMAsyA@Ck6+PirkwpXP)r%Le@MS zrv|f(FWw8oPV?P?ANP|}?{h<0IP7+`SU1!uzn-Xat}E)7vhrK6yWY!(%Bf9wbzpN8 zKz|#!JM#0wP`~FaBS|SsQbLKUn&cTH!t{l}tB!ZKUcCFtEa8vmuX(iQHscg!c{faY z%_^kI%`@%O2hwX^wp6JiDYVtdXDf~a%ZzQs$@#fMSsbm=c6STCCbS^GUqZ9<{`QZkta*`gRD+)KIgLJ zdTW+dhHvM*>xqG5Vpdi{8z-C%^nr(gSx!+J%379Y>QE3Lsf%iY;xSnhO`B_rmj!=% z(0q~8olgs9P9@s@MPr