diff options
-rw-r--r-- | CMakeLists.txt | 9 | ||||
-rw-r--r-- | include-gpl/gui/glspectrum.h | 4 | ||||
-rw-r--r-- | include-gpl/gui/glspectrumguismall.h | 63 | ||||
-rw-r--r-- | include/gui/rollupwidget.h | 3 | ||||
-rw-r--r-- | plugins/channel/tcpsrc/tcpsrc.cpp | 19 | ||||
-rw-r--r-- | plugins/channel/tcpsrc/tcpsrc.h | 21 | ||||
-rw-r--r-- | plugins/channel/tcpsrc/tcpsrcgui.cpp | 14 | ||||
-rw-r--r-- | plugins/channel/tcpsrc/tcpsrcgui.h | 2 | ||||
-rw-r--r-- | plugins/channel/tcpsrc/tcpsrcgui.ui | 9 | ||||
-rw-r--r-- | sdrbase/gui/glspectrum.cpp | 117 | ||||
-rw-r--r-- | sdrbase/gui/glspectrumguismall.cpp | 196 | ||||
-rw-r--r-- | sdrbase/gui/glspectrumguismall.ui | 439 | ||||
-rw-r--r-- | sdrbase/gui/rollupwidget.cpp | 20 | ||||
-rw-r--r-- | sdrbase/resources/grid.png | bin | 0 -> 259 bytes | |||
-rw-r--r-- | sdrbase/resources/res.qrc | 1 |
15 files changed, 879 insertions, 38 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index fe5cbf9..c388954 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,9 +3,9 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) project(sdrangelove) -#set(CMAKE_BUILD_TYPE "Release") -#set(CMAKE_BUILD_TYPE "ReleaseWithDebInfo") -set(CMAKE_BUILD_TYPE "Debug") +set(CMAKE_BUILD_TYPE "Release") +#set(CMAKE_BUILD_TYPE "ReleaseWithDebugInfo") +#set(CMAKE_BUILD_TYPE "Debug") set(QT_USE_QTOPENGL TRUE) set(CMAKE_AUTOMOC ON) @@ -68,6 +68,7 @@ set(sdrbase_SOURCES sdrbase/gui/glscope.cpp sdrbase/gui/glspectrum.cpp sdrbase/gui/glspectrumgui.cpp + sdrbase/gui/glspectrumguismall.cpp sdrbase/gui/indicator.cpp sdrbase/gui/pluginsdialog.cpp sdrbase/gui/preferencesdialog.cpp @@ -132,6 +133,7 @@ set(sdrbase_HEADERS include-gpl/gui/glscope.h include-gpl/gui/glspectrum.h include-gpl/gui/glspectrumgui.h + include-gpl/gui/glspectrumguismall.h include-gpl/gui/indicator.h include-gpl/gui/physicalunit.h include-gpl/gui/pluginsdialog.h @@ -173,6 +175,7 @@ set(sdrbase_FORMS sdrbase/gui/aboutdialog.ui sdrbase/gui/addpresetdialog.ui sdrbase/gui/glspectrumgui.ui + sdrbase/gui/glspectrumguismall.ui sdrbase/gui/pluginsdialog.ui sdrbase/gui/preferencesdialog.ui sdrbase/gui/scopewindow.ui diff --git a/include-gpl/gui/glspectrum.h b/include-gpl/gui/glspectrum.h index e5e05f0..cbe22a9 100644 --- a/include-gpl/gui/glspectrum.h +++ b/include-gpl/gui/glspectrum.h @@ -37,10 +37,12 @@ public: void setSampleRate(qint32 sampleRate); void setReferenceLevel(Real referenceLevel); void setPowerRange(Real powerRange); + void setDecay(int decay); void setDisplayWaterfall(bool display); void setInvertedWaterfall(bool inv); void setDisplayMaxHold(bool display); void setDisplayHistogram(bool display); + void setDisplayGrid(bool display); void addChannelMarker(ChannelMarker* channelMarker); void removeChannelMarker(ChannelMarker* channelMarker); @@ -78,10 +80,12 @@ private: qint64 m_centerFrequency; Real m_referenceLevel; Real m_powerRange; + int m_decay; quint32 m_sampleRate; int m_fftSize; + bool m_displayGrid; bool m_invertedWaterfall; std::vector<Real> m_maxHold; diff --git a/include-gpl/gui/glspectrumguismall.h b/include-gpl/gui/glspectrumguismall.h new file mode 100644 index 0000000..67cad73 --- /dev/null +++ b/include-gpl/gui/glspectrumguismall.h @@ -0,0 +1,63 @@ +#ifndef INCLUDE_GLSPECTRUMGUISMALL_H +#define INCLUDE_GLSPECTRUMGUISMALL_H + +#include <QWidget> +#include "dsp/dsptypes.h" +#include "util/export.h" + +namespace Ui { + class GLSpectrumGUISmall; +} + +class MessageQueue; +class SpectrumVis; +class GLSpectrum; + +class SDRANGELOVE_API GLSpectrumGUISmall : public QWidget { + Q_OBJECT + +public: + explicit GLSpectrumGUISmall(QWidget* parent = NULL); + ~GLSpectrumGUISmall(); + + void setBuddies(MessageQueue* messageQueue, SpectrumVis* spectrumVis, GLSpectrum* glSpectrum); + + void resetToDefaults(); + QByteArray serialize() const; + bool deserialize(const QByteArray& data); + +private: + Ui::GLSpectrumGUISmall* ui; + + MessageQueue* m_messageQueue; + SpectrumVis* m_spectrumVis; + GLSpectrum* m_glSpectrum; + + qint32 m_fftSize; + qint32 m_fftOverlap; + qint32 m_fftWindow; + Real m_refLevel; + Real m_powerRange; + int m_decay; + bool m_displayWaterfall; + bool m_invertedWaterfall; + bool m_displayMaxHold; + bool m_displayHistogram; + bool m_displayGrid; + + void applySettings(); + +private slots: + void on_fftWindow_currentIndexChanged(int index); + void on_fftSize_currentIndexChanged(int index); + void on_refLevel_currentIndexChanged(int index); + void on_levelRange_currentIndexChanged(int index); + void on_decay_currentIndexChanged(int index); + + void on_waterfall_toggled(bool checked); + void on_histogram_toggled(bool checked); + void on_maxHold_toggled(bool checked); + void on_grid_toggled(bool checked); +}; + +#endif // INCLUDE_GLSPECTRUMGUISMALL_H diff --git a/include/gui/rollupwidget.h b/include/gui/rollupwidget.h index 8860410..ddebe6a 100644 --- a/include/gui/rollupwidget.h +++ b/include/gui/rollupwidget.h @@ -13,6 +13,9 @@ public: QByteArray saveState(int version = 0) const; bool restoreState(const QByteArray& state, int version = 0); +signals: + void widgetRolled(QWidget* widget, bool rollDown); + protected: enum { VersionMarker = 0xff diff --git a/plugins/channel/tcpsrc/tcpsrc.cpp b/plugins/channel/tcpsrc/tcpsrc.cpp index 395ab7b..02a55d2 100644 --- a/plugins/channel/tcpsrc/tcpsrc.cpp +++ b/plugins/channel/tcpsrc/tcpsrc.cpp @@ -7,6 +7,7 @@ MessageRegistrator TCPSrc::MsgTCPSrcConfigure::ID("MsgTCPSrcConfigure"); MessageRegistrator TCPSrc::MsgTCPSrcConnection::ID("MsgTCPSrcConnection"); +MessageRegistrator TCPSrc::MsgTCPSrcSpectrum::ID("MsgTCPSrcSpectrum"); TCPSrc::TCPSrc(MessageQueue* uiMessageQueue, TCPSrcGUI* tcpSrcGUI, SampleSink* spectrum) { @@ -21,6 +22,7 @@ TCPSrc::TCPSrc(MessageQueue* uiMessageQueue, TCPSrcGUI* tcpSrcGUI, SampleSink* s m_uiMessageQueue = uiMessageQueue; m_tcpSrcGUI = tcpSrcGUI; m_spectrum = spectrum; + m_spectrumEnabled = false; m_nextS8Id = 0; m_nextS16leId = 0; } @@ -35,6 +37,12 @@ void TCPSrc::configure(MessageQueue* messageQueue, SampleFormat sampleFormat, Re cmd->submit(messageQueue, this); } +void TCPSrc::setSpectrum(MessageQueue* messageQueue, bool enabled) +{ + Message* cmd = MsgTCPSrcSpectrum::create(enabled); + cmd->submit(messageQueue, this); +} + void TCPSrc::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst) { Complex ci; @@ -51,7 +59,7 @@ void TCPSrc::feed(SampleVector::const_iterator begin, SampleVector::const_iterat } } - if(m_spectrum != NULL) + if((m_spectrum != NULL) && (m_spectrumEnabled)) m_spectrum->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), firstOfBurst); for(int i = 0; i < m_s16leSockets.count(); i++) @@ -113,8 +121,15 @@ bool TCPSrc::handleMessage(Message* cmd) m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate; cmd->completed(); return true; + } else if(cmd->id() == MsgTCPSrcSpectrum::ID()) { + MsgTCPSrcSpectrum* spc = (MsgTCPSrcSpectrum*)cmd; + m_spectrumEnabled = spc->getEnabled(); + cmd->completed(); + return true; } else { - return false; + if(m_spectrum != NULL) + return m_spectrum->handleMessage(cmd); + else return false; } } diff --git a/plugins/channel/tcpsrc/tcpsrc.h b/plugins/channel/tcpsrc/tcpsrc.h index 9c43bac..a8270ff 100644 --- a/plugins/channel/tcpsrc/tcpsrc.h +++ b/plugins/channel/tcpsrc/tcpsrc.h @@ -24,6 +24,7 @@ public: ~TCPSrc(); void configure(MessageQueue* messageQueue, SampleFormat sampleFormat, Real outputSampleRate, Real rfBandwidth, int tcpPort); + void setSpectrum(MessageQueue* messageQueue, bool enabled); void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst); void start(); @@ -88,6 +89,25 @@ protected: m_tcpPort(tcpPort) { } }; + class MsgTCPSrcSpectrum : public Message { + public: + static MessageRegistrator ID; + + bool getEnabled() const { return m_enabled; } + + static MsgTCPSrcSpectrum* create(bool enabled) + { + return new MsgTCPSrcSpectrum(enabled); + } + + private: + bool m_enabled; + + MsgTCPSrcSpectrum(bool enabled) : + Message(ID()), + m_enabled(enabled) + { } + }; MessageQueue* m_uiMessageQueue; TCPSrcGUI* m_tcpSrcGUI; @@ -106,6 +126,7 @@ protected: SampleVector m_sampleBuffer; std::vector<qint8> m_sampleBufferS8; SampleSink* m_spectrum; + bool m_spectrumEnabled; QTcpServer* m_tcpServer; struct Socket { diff --git a/plugins/channel/tcpsrc/tcpsrcgui.cpp b/plugins/channel/tcpsrc/tcpsrcgui.cpp index dbaa52f..92f210e 100644 --- a/plugins/channel/tcpsrc/tcpsrcgui.cpp +++ b/plugins/channel/tcpsrc/tcpsrcgui.cpp @@ -29,6 +29,7 @@ void TCPSrcGUI::resetToDefaults() ui->sampleRate->setText("25000"); ui->rfBandwidth->setText("20000"); ui->tcpPort->setText("9999"); + ui->spectrumGUI->resetToDefaults(); applySettings(); } @@ -41,6 +42,7 @@ QByteArray TCPSrcGUI::serialize() const s.writeReal(4, m_outputSampleRate); s.writeReal(5, m_rfBandwidth); s.writeS32(6, m_tcpPort); + s.writeBlob(7, ui->spectrumGUI->serialize()); return s.final(); } @@ -79,6 +81,8 @@ bool TCPSrcGUI::deserialize(const QByteArray& data) ui->rfBandwidth->setText(QString("%1").arg(realtmp, 0)); d.readS32(6, &s32tmp, 9999); ui->tcpPort->setText(QString("%1").arg(s32tmp)); + d.readBlob(7, &bytetmp); + ui->spectrumGUI->deserialize(bytetmp); applySettings(); return true; } else { @@ -111,8 +115,10 @@ TCPSrcGUI::TCPSrcGUI(PluginAPI* pluginAPI, QWidget* parent) : ui(new Ui::TCPSrcGUI), m_pluginAPI(pluginAPI) { + m_tcpSrc = NULL; ui->setupUi(this); ui->connectedClientsBox->hide(); + connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); setAttribute(Qt::WA_DeleteOnClose, true); m_spectrumVis = new SpectrumVis(ui->glSpectrum); @@ -135,6 +141,8 @@ TCPSrcGUI::TCPSrcGUI(PluginAPI* pluginAPI, QWidget* parent) : connect(m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged())); m_pluginAPI->addChannelMarker(m_channelMarker); + ui->spectrumGUI->setBuddies(m_threadedSampleSink->getMessageQueue(), m_spectrumVis, ui->glSpectrum); + applySettings(); } @@ -228,6 +236,12 @@ void TCPSrcGUI::on_applyBtn_clicked() applySettings(); } +void TCPSrcGUI::onWidgetRolled(QWidget* widget, bool rollDown) +{ + if((widget == ui->spectrumBox) && (m_tcpSrc != NULL)) + m_tcpSrc->setSpectrum(m_threadedSampleSink->getMessageQueue(), rollDown); +} + void TCPSrcGUI::addConnection(quint32 id, const QHostAddress& peerAddress, int peerPort) { QStringList l; diff --git a/plugins/channel/tcpsrc/tcpsrcgui.h b/plugins/channel/tcpsrc/tcpsrcgui.h index e8ebe5b..c2c1614 100644 --- a/plugins/channel/tcpsrc/tcpsrcgui.h +++ b/plugins/channel/tcpsrc/tcpsrcgui.h @@ -38,8 +38,8 @@ private slots: 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(); + void onWidgetRolled(QWidget* widget, bool rollDown); private: Ui::TCPSrcGUI* ui; diff --git a/plugins/channel/tcpsrc/tcpsrcgui.ui b/plugins/channel/tcpsrc/tcpsrcgui.ui index e3549fe..c92c6a7 100644 --- a/plugins/channel/tcpsrc/tcpsrcgui.ui +++ b/plugins/channel/tcpsrc/tcpsrcgui.ui @@ -129,6 +129,9 @@ <item> <widget class="GLSpectrum" name="glSpectrum" native="true"/> </item> + <item> + <widget class="GLSpectrumGUISmall" name="spectrumGUI" native="true"/> + </item> </layout> </widget> <widget class="QWidget" name="connectedClientsBox" native="true"> @@ -184,6 +187,12 @@ <header>gui/glspectrum.h</header> <container>1</container> </customwidget> + <customwidget> + <class>GLSpectrumGUISmall</class> + <extends>QWidget</extends> + <header>gui/glspectrumguismall.h</header> + <container>1</container> + </customwidget> </customwidgets> <tabstops> <tabstop>sampleFormat</tabstop> diff --git a/sdrbase/gui/glspectrum.cpp b/sdrbase/gui/glspectrum.cpp index d9e33be..b365bbe 100644 --- a/sdrbase/gui/glspectrum.cpp +++ b/sdrbase/gui/glspectrum.cpp @@ -26,8 +26,10 @@ GLSpectrum::GLSpectrum(QWidget* parent) : m_centerFrequency(100000000), m_referenceLevel(0), m_powerRange(100), + m_decay(0), m_sampleRate(500000), m_fftSize(512), + m_displayGrid(true), m_invertedWaterfall(false), m_displayMaxHold(false), m_leftMarginTextureAllocated(false), @@ -158,6 +160,15 @@ void GLSpectrum::setPowerRange(Real powerRange) update(); } +void GLSpectrum::setDecay(int decay) +{ + m_decay = decay; + if(m_decay < -2) + m_decay = -2; + else if(m_decay > 2) + m_decay = 2; +} + void GLSpectrum::setSampleRate(qint32 sampleRate) { m_sampleRate = sampleRate; @@ -197,6 +208,12 @@ void GLSpectrum::setDisplayHistogram(bool display) update(); } +void GLSpectrum::setDisplayGrid(bool display) +{ + m_displayGrid = display; + update(); +} + void GLSpectrum::addChannelMarker(ChannelMarker* channelMarker) { QMutexLocker mutexLocker(&m_mutex); @@ -271,14 +288,20 @@ void GLSpectrum::updateHistogram(const std::vector<Real>& spectrum) { quint8* b = m_histogram; quint8* h = m_histogramHoldoff; + int sub = 1; + + if(m_decay > 0) + sub += m_decay; m_histogramHoldoffCount--; if(m_histogramHoldoffCount <= 0) { for(int i = 0; i < 100 * m_fftSize; i++) { if(*b > 20) { - *b = *b - 1; + *b = *b - sub; } else if(*b > 0) { - if(*h > 0) { + if(*h >= sub) { + *h = *h - sub; + } else if(*h > 0) { *h = *h - 1; } else { *b = *b - 1; @@ -305,28 +328,67 @@ void GLSpectrum::updateHistogram(const std::vector<Real>& spectrum) } } #else - const __m128 refl = {m_referenceLevel,m_referenceLevel,m_referenceLevel,m_referenceLevel}; - const __m128 power = {m_powerRange,m_powerRange,m_powerRange,m_powerRange}; - const __m128 mul = {100.0f,100.0f,100.0f,100.0f}; - - for(int i = 0; i < m_fftSize; i+=4) { - __m128 abc = _mm_loadu_ps (&spectrum[i]); - abc = _mm_sub_ps(abc, refl); - abc = _mm_mul_ps(abc, mul); - abc = _mm_div_ps(abc, power); - abc = _mm_add_ps(abc, mul); - __m128i result = _mm_cvtps_epi32(abc); - - for(int j = 0; j < 4; j++) { - - int v = ((int*)&result)[j]; - - if((v >= 0) && (v <= 99)) { - b = m_histogram + (i+j) * 100 + v; - if(*b < 220) - *b += 4; - else if(*b < 239) - *b += 1; + if(m_decay >= 0) { // normal + const __m128 refl = {m_referenceLevel, m_referenceLevel, m_referenceLevel, m_referenceLevel}; + const __m128 power = {m_powerRange, m_powerRange, m_powerRange, m_powerRange}; + const __m128 mul = {100.0f, 100.0f, 100.0f, 100.0f}; + + for(int i = 0; i < m_fftSize; i += 4) { + __m128 abc = _mm_loadu_ps (&spectrum[i]); + abc = _mm_sub_ps(abc, refl); + abc = _mm_mul_ps(abc, mul); + abc = _mm_div_ps(abc, power); + abc = _mm_add_ps(abc, mul); + __m128i result = _mm_cvtps_epi32(abc); + + for(int j = 0; j < 4; j++) { + int v = ((int*)&result)[j]; + if((v >= 0) && (v <= 99)) { + b = m_histogram + (i + j) * 100 + v; + if(*b < 220) + *b += 4; + else if(*b < 239) + *b += 1; + } + } + } + } else { // draw double pixels + int add = -m_decay * 4; + const __m128 refl = {m_referenceLevel, m_referenceLevel, m_referenceLevel, m_referenceLevel}; + const __m128 power = {m_powerRange, m_powerRange, m_powerRange, m_powerRange}; + const __m128 mul = {100.0f, 100.0f, 100.0f, 100.0f}; + + for(int i = 0; i < m_fftSize; i += 4) { + __m128 abc = _mm_loadu_ps (&spectrum[i]); + abc = _mm_sub_ps(abc, refl); + abc = _mm_mul_ps(abc, mul); + abc = _mm_div_ps(abc, power); + abc = _mm_add_ps(abc, mul); + __m128i result = _mm_cvtps_epi32(abc); + + for(int j = 0; j < 4; j++) { + int v = ((int*)&result)[j]; + if((v >= 1) && (v <= 98)) { + b = m_histogram + (i + j) * 100 + v; + if(b[-1] < 220) + b[-1] += add; + else if(b[-1] < 239) + b[-1] += 1; + if(b[0] < 220) + b[0] += add; + else if(b[0] < 239) + b[0] += 1; + if(b[1] < 220) + b[1] += add; + else if(b[0] < 239) + b[1] += 1; + } else if((v >= 0) && (v <= 99)) { + b = m_histogram + (i + j) * 100 + v; + if(*b < 220) + *b += add; + else if(*b < 239) + *b += 1; + } } } } @@ -603,10 +665,11 @@ void GLSpectrum::paintGL() for(int i = 0; i < m_fftSize; i++) { int j; quint8* bs = m_histogram + i * 100; - for(j = 99; j > 0; j--) { + for(j = 99; j > 1; j--) { if(bs[j] > 0) break; } + // TODO: ((bs[j] * (float)j) + (bs[j + 1] * (float)(j + 1))) / (bs[j] + bs[j + 1]) j = j - 99; m_maxHold[i] = (j * m_powerRange) / 99.0 + m_referenceLevel; } @@ -635,7 +698,7 @@ void GLSpectrum::paintGL() } // paint waterfall grid - if(m_displayWaterfall) { + if(m_displayWaterfall && m_displayGrid) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glLineWidth(1.0f); @@ -680,7 +743,7 @@ void GLSpectrum::paintGL() } // paint histogram grid - if(m_displayHistogram || m_displayMaxHold) { + if((m_displayHistogram || m_displayMaxHold) && (m_displayGrid)) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glLineWidth(1.0f); diff --git a/sdrbase/gui/glspectrumguismall.cpp b/sdrbase/gui/glspectrumguismall.cpp new file mode 100644 index 0000000..85be4ff --- /dev/null +++ b/sdrbase/gui/glspectrumguismall.cpp @@ -0,0 +1,196 @@ +#include "gui/glspectrumguismall.h" +#include "dsp/fftwindow.h" +#include "dsp/spectrumvis.h" +#include "gui/glspectrum.h" +#include "util/simpleserializer.h" +#include "ui_glspectrumguismall.h" + +GLSpectrumGUISmall::GLSpectrumGUISmall(QWidget* parent) : + QWidget(parent), + ui(new Ui::GLSpectrumGUISmall), + m_messageQueue(NULL), + m_spectrumVis(NULL), + m_glSpectrum(NULL), + m_fftSize(1024), + m_fftOverlap(10), + m_fftWindow(FFTWindow::Hamming), + m_refLevel(0), + m_powerRange(100), + m_decay(0), + m_displayWaterfall(true), + m_invertedWaterfall(false), + m_displayMaxHold(false), + m_displayHistogram(true) +{ + ui->setupUi(this); + for(int ref = 0; ref >= -95; ref -= 5) + ui->refLevel->addItem(QString("%1").arg(ref)); + for(int range = 100; range >= 5; range -= 5) + ui->levelRange->addItem(QString("%1").arg(range)); +} + +GLSpectrumGUISmall::~GLSpectrumGUISmall() +{ + delete ui; +} + +void GLSpectrumGUISmall::setBuddies(MessageQueue* messageQueue, SpectrumVis* spectrumVis, GLSpectrum* glSpectrum) +{ + m_messageQueue = messageQueue; + m_spectrumVis = spectrumVis; + m_glSpectrum = glSpectrum; + applySettings(); +} + +void GLSpectrumGUISmall::resetToDefaults() +{ + m_fftSize = 1024; + m_fftOverlap = 10; + m_fftWindow = FFTWindow::Hamming; + m_refLevel = 0; + m_powerRange = 100; + m_decay = 0; + m_displayWaterfall = true; + m_invertedWaterfall = false; + m_displayMaxHold = false; + m_displayHistogram = true; + m_displayGrid = true; + applySettings(); +} + +QByteArray GLSpectrumGUISmall::serialize() const +{ + SimpleSerializer s(1); + s.writeS32(1, m_fftSize); + s.writeS32(2, m_fftOverlap); + s.writeS32(3, m_fftWindow); + s.writeReal(4, m_refLevel); + s.writeReal(5, m_powerRange); + s.writeBool(6, m_displayWaterfall); + s.writeBool(7, m_invertedWaterfall); + s.writeBool(8, m_displayMaxHold); + s.writeBool(9, m_displayHistogram); + s.writeS32(10, m_decay); + s.writeBool(11, m_displayGrid); + return s.final(); +} + +bool GLSpectrumGUISmall::deserialize(const QByteArray& data) +{ + SimpleDeserializer d(data); + + if(!d.isValid()) { + resetToDefaults(); + return false; + } + + if(d.getVersion() == 1) { + d.readS32(1, &m_fftSize, 1024); + d.readS32(2, &m_fftOverlap, 10); + d.readS32(3, &m_fftWindow, FFTWindow::Hamming); + d.readReal(4, &m_refLevel, 0); + d.readReal(5, &m_powerRange, 100); + d.readBool(6, &m_displayWaterfall, true); + d.readBool(7, &m_invertedWaterfall, false); + d.readBool(8, &m_displayMaxHold, false); + d.readBool(9, &m_displayHistogram, true); + d.readS32(10, &m_decay, 0); + d.readBool(11, &m_displayGrid, true); + applySettings(); + return true; + } else { + resetToDefaults(); + return false; + } +} + +void GLSpectrumGUISmall::applySettings() +{ + ui->fftWindow->setCurrentIndex(m_fftWindow); + for(int i = 0; i < 6; i++) { + if(m_fftSize == (1 << (i + 7))) { + ui->fftSize->setCurrentIndex(i); + break; + } + } + ui->refLevel->setCurrentIndex(-m_refLevel / 5); + ui->levelRange->setCurrentIndex((100 - m_powerRange) / 5); + ui->decay->setCurrentIndex(m_decay + 2); + ui->waterfall->setChecked(m_displayWaterfall); + ui->maxHold->setChecked(m_displayMaxHold); + ui->histogram->setChecked(m_displayHistogram); + ui->grid->setChecked(m_displayGrid); + + m_glSpectrum->setDisplayWaterfall(m_displayWaterfall); + m_glSpectrum->setInvertedWaterfall(m_invertedWaterfall); + m_glSpectrum->setDisplayMaxHold(m_displayMaxHold); + m_glSpectrum->setDisplayHistogram(m_displayHistogram); + m_glSpectrum->setDecay(m_decay); + m_glSpectrum->setDisplayGrid(m_displayGrid); + + m_spectrumVis->configure(m_messageQueue, m_fftSize, m_fftOverlap, (FFTWindow::Function)m_fftWindow); +} + +void GLSpectrumGUISmall::on_fftWindow_currentIndexChanged(int index) +{ + m_fftWindow = index; + if(m_spectrumVis == NULL) + return; + m_spectrumVis->configure(m_messageQueue, m_fftSize, m_fftOverlap, (FFTWindow::Function)m_fftWindow); +} + +void GLSpectrumGUISmall::on_fftSize_currentIndexChanged(int index) +{ + m_fftSize = 1 << (7 + index); + if(m_spectrumVis != NULL) + m_spectrumVis->configure(m_messageQueue, m_fftSize, m_fftOverlap, (FFTWindow::Function)m_fftWindow); +} + +void GLSpectrumGUISmall::on_refLevel_currentIndexChanged(int index) +{ + m_refLevel = 0 - index * 5; + if(m_glSpectrum != NULL) + m_glSpectrum->setReferenceLevel(m_refLevel); +} + +void GLSpectrumGUISmall::on_levelRange_currentIndexChanged(int index) +{ + m_powerRange = 100 - index * 5; + if(m_glSpectrum != NULL) + m_glSpectrum->setPowerRange(m_powerRange); +} + +void GLSpectrumGUISmall::on_decay_currentIndexChanged(int index) +{ + m_decay = index - 2; + if(m_glSpectrum != NULL) + m_glSpectrum->setDecay(m_decay); +} + +void GLSpectrumGUISmall::on_waterfall_toggled(bool checked) +{ + m_displayWaterfall = checked; + if(m_glSpectrum != NULL) + m_glSpectrum->setDisplayWaterfall(m_displayWaterfall); +} + +void GLSpectrumGUISmall::on_histogram_toggled(bool checked) +{ + m_displayHistogram = checked; + if(m_glSpectrum != NULL) + m_glSpectrum->setDisplayHistogram(m_displayHistogram); +} + +void GLSpectrumGUISmall::on_maxHold_toggled(bool checked) +{ + m_displayMaxHold = checked; + if(m_glSpectrum != NULL) + m_glSpectrum->setDisplayMaxHold(m_displayMaxHold); +} + +void GLSpectrumGUISmall::on_grid_toggled(bool checked) +{ + m_displayGrid = checked; + if(m_glSpectrum != NULL) + m_glSpectrum->setDisplayGrid(m_displayGrid); +} diff --git a/sdrbase/gui/glspectrumguismall.ui b/sdrbase/gui/glspectrumguismall.ui new file mode 100644 index 0000000..2981ffe --- /dev/null +++ b/sdrbase/gui/glspectrumguismall.ui @@ -0,0 +1,439 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>GLSpectrumGUISmall</class> + <widget class="QWidget" name="GLSpectrumGUISmall"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>214</width> + <height>94</height> + </rect> + </property> + <property name="windowTitle"> + <string>Oscilloscope</string> + </property> + <layout class="QGridLayout" name="gridLayout" columnstretch="1,1,1,1"> + <property name="margin"> + <number>2</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label_17"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Window</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_18"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>FFT Size</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="label_19"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Ref (dB)</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="label_20"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Range (dB)</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QComboBox" name="fftWindow"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Ignored" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>FFT window function</string> + </property> + <property name="sizeAdjustPolicy"> + <enum>QComboBox::AdjustToContents</enum> + </property> + <item> + <property name="text"> + <string>Bartlett</string> + </property> + </item> + <item> + <property name="text"> + <string>Blackman-Harris</string> + </property> + </item> + <item> + <property name="text"> + <string>Flat Top</string> + </property> + </item> + <item> + <property name="text"> + <string>Hamming</string> + </property> + </item> + <item> + <property name="text"> + <string>Hanning</string> + </property> + </item> + <item> + <property name="text"> + <string>Rectangle</string> + </property> + </item> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="fftSize"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Ignored" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>FFT window function</string> + </property> + <property name="sizeAdjustPolicy"> + <enum>QComboBox::AdjustToContents</enum> + </property> + <item> + <property name="text"> + <string>128</string> + </property> + </item> + <item> + <property name="text"> + <string>256</string> + </property> + </item> + <item> + <property name="text"> + <string>512</string> + </property> + </item> + <item> + <property name="text"> + <string>1024</string> + </property> + </item> + <item> + <property name="text"> + <string>2048</string> + </property> + </item> + <item> + <property name="text"> + <string>4096</string> + </property> + </item> + </widget> + </item> + <item row="1" column="2"> + <widget class="QComboBox" name="refLevel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Ignored" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>FFT window function</string> + </property> + <property name="sizeAdjustPolicy"> + <enum>QComboBox::AdjustToContents</enum> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QComboBox" name="levelRange"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Ignored" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>FFT window function</string> + </property> + <property name="sizeAdjustPolicy"> + <enum>QComboBox::AdjustToContents</enum> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_8"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Decay</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QComboBox" name="decay"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Ignored" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>FFT window function</string> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <property name="sizeAdjustPolicy"> + <enum>QComboBox::AdjustToContents</enum> + </property> + <item> + <property name="text"> + <string>-2</string> + </property> + </item> + <item> + <property name="text"> + <string>-1</string> + </property> + </item> + <item> + <property name="text"> + <string>normal</string> + </property> + </item> + <item> + <property name="text"> + <string>+1</string> + </property> + </item> + <item> + <property name="text"> + <string>+2</string> + </property> + </item> + </widget> + </item> + <item row="3" column="1" colspan="3"> + <layout class="QHBoxLayout" name="controlBtns"> + <property name="spacing"> + <number>3</number> + </property> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="ButtonSwitch" name="waterfall"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + <property name="toolTip"> + <string>Display waterfall</string> + </property> + <property name="text"> + <string>Waterfall</string> + </property> + <property name="icon"> + <iconset resource="../resources/res.qrc"> + <normaloff>:/waterfall.png</normaloff>:/waterfall.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="ButtonSwitch" name="histogram"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + <property name="toolTip"> + <string>Display phosphor effect spectrum</string> + </property> + <property name="text"> + <string>Histogram</string> + </property> + <property name="icon"> + <iconset resource="../resources/res.qrc"> + <normaloff>:/histogram.png</normaloff>:/histogram.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="ButtonSwitch" name="maxHold"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + <property name="toolTip"> + <string>Display live spectrum</string> + </property> + <property name="text"> + <string>Live Spectrum</string> + </property> + <property name="icon"> + <iconset resource="../resources/res.qrc"> + <normaloff>:/maxhold.png</normaloff>:/maxhold.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="ButtonSwitch" name="grid"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + <property name="toolTip"> + <string>Toggle the scale grid</string> + </property> + <property name="text"> + <string>Grid</string> + </property> + <property name="icon"> + <iconset resource="../resources/res.qrc"> + <normaloff>:/grid.png</normaloff>:/grid.png</iconset> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>ButtonSwitch</class> + <extends>QToolButton</extends> + <header>gui/buttonswitch.h</header> + </customwidget> + </customwidgets> + <tabstops> + <tabstop>fftWindow</tabstop> + <tabstop>fftSize</tabstop> + <tabstop>refLevel</tabstop> + <tabstop>levelRange</tabstop> + <tabstop>decay</tabstop> + <tabstop>waterfall</tabstop> + <tabstop>histogram</tabstop> + <tabstop>maxHold</tabstop> + </tabstops> + <resources> + <include location="../resources/res.qrc"/> + </resources> + <connections/> +</ui> diff --git a/sdrbase/gui/rollupwidget.cpp b/sdrbase/gui/rollupwidget.cpp index 39bcd55..db735c2 100644 --- a/sdrbase/gui/rollupwidget.cpp +++ b/sdrbase/gui/rollupwidget.cpp @@ -8,7 +8,6 @@ RollupWidget::RollupWidget(QWidget* parent) : QWidget(parent) { setMinimumSize(250, 150); - setMaximumSize(400, 200); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setBackgroundRole(QPalette::Window); @@ -279,9 +278,13 @@ void RollupWidget::mousePressEvent(QMouseEvent* event) QWidget* r = qobject_cast<QWidget*>(children()[i]); if(r != NULL) { if((event->y() >= pos) && (event->y() < (pos + fm.height() + 3))) { - if(r->isHidden()) + if(r->isHidden()) { r->show(); - else r->hide(); + //emit widgetRolled(r, true); + } else { + r->hide(); + //emit widgetRolled(r, false); + } arrangeRollups(); repaint(); return; @@ -308,9 +311,16 @@ bool RollupWidget::event(QEvent* event) bool RollupWidget::eventFilter(QObject* object, QEvent* event) { - if((event->type() == QEvent::Show) || (event->type() == QEvent::Hide)) { - if(children().contains(object)) + if(event->type() == QEvent::Show) { + if(children().contains(object)) { arrangeRollups(); + emit widgetRolled(qobject_cast<QWidget*>(object), true); + } + } else if(event->type() == QEvent::Hide) { + if(children().contains(object)) { + arrangeRollups(); + emit widgetRolled(qobject_cast<QWidget*>(object), false); + } } else if(event->type() == QEvent::WindowTitleChange) { if(children().contains(object)) repaint(); diff --git a/sdrbase/resources/grid.png b/sdrbase/resources/grid.png Binary files differnew file mode 100644 index 0000000..e384a53 --- /dev/null +++ b/sdrbase/resources/grid.png diff --git a/sdrbase/resources/res.qrc b/sdrbase/resources/res.qrc index 0d2ecd6..6130fc0 100644 --- a/sdrbase/resources/res.qrc +++ b/sdrbase/resources/res.qrc @@ -10,5 +10,6 @@ <file>vertical.png</file> <file>logo.png</file> <file>maxhold.png</file> + <file>grid.png</file> </qresource> </RCC> |