summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Daniel <cd@maintech.de>2013-09-27 16:30:58 +0200
committerChristian Daniel <cd@maintech.de>2013-09-27 16:30:58 +0200
commit710be6e71904f311996e5f9167bdf2d0b1f145d7 (patch)
treeb205516e8148c2ee94de740898199f9b98bf550b
parent3119c17e2c68381444634c999858b10e5df79daa (diff)
Improve spectrum view and other GUI polish
-rw-r--r--CMakeLists.txt9
-rw-r--r--include-gpl/gui/glspectrum.h4
-rw-r--r--include-gpl/gui/glspectrumguismall.h63
-rw-r--r--include/gui/rollupwidget.h3
-rw-r--r--plugins/channel/tcpsrc/tcpsrc.cpp19
-rw-r--r--plugins/channel/tcpsrc/tcpsrc.h21
-rw-r--r--plugins/channel/tcpsrc/tcpsrcgui.cpp14
-rw-r--r--plugins/channel/tcpsrc/tcpsrcgui.h2
-rw-r--r--plugins/channel/tcpsrc/tcpsrcgui.ui9
-rw-r--r--sdrbase/gui/glspectrum.cpp117
-rw-r--r--sdrbase/gui/glspectrumguismall.cpp196
-rw-r--r--sdrbase/gui/glspectrumguismall.ui439
-rw-r--r--sdrbase/gui/rollupwidget.cpp20
-rw-r--r--sdrbase/resources/grid.pngbin0 -> 259 bytes
-rw-r--r--sdrbase/resources/res.qrc1
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
new file mode 100644
index 0000000..e384a53
--- /dev/null
+++ b/sdrbase/resources/grid.png
Binary files differ
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>