1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-26 01:39:05 -05:00

Spectrum frequency zoom: UI implementation and messaging to spectrum vis

This commit is contained in:
f4exb 2021-02-15 13:49:51 +01:00
parent 166089a8bd
commit ab0a7f2e60
6 changed files with 135 additions and 26 deletions

View File

@ -26,7 +26,7 @@ class GLSpectrumInterface
public:
GLSpectrumInterface() {}
virtual ~GLSpectrumInterface() {}
virtual void newSpectrum(const std::vector<Real>& spectrum, int fftSize)
virtual void newSpectrum(const Real* spectrum, int fftSize)
{
(void) spectrum;
(void) fftSize;

View File

@ -44,6 +44,7 @@ MESSAGE_CLASS_DEFINITION(SpectrumVis::MsgConfigureScalingFactor, Message)
MESSAGE_CLASS_DEFINITION(SpectrumVis::MsgConfigureWSpectrumOpenClose, Message)
MESSAGE_CLASS_DEFINITION(SpectrumVis::MsgConfigureWSpectrum, Message)
MESSAGE_CLASS_DEFINITION(SpectrumVis::MsgStartStop, Message)
MESSAGE_CLASS_DEFINITION(SpectrumVis::MsgFrequencyZooming, Message)
const Real SpectrumVis::m_mult = (10.0f / log2(10.0f));
@ -57,6 +58,8 @@ SpectrumVis::SpectrumVis(Real scalef) :
m_psd(MAX_FFT_SIZE),
m_fftBufferFill(0),
m_needMoreSamples(false),
m_frequencyZoomFactor(1.0f),
m_frequencyZoomPos(0.5f),
m_scalef(scalef),
m_glSpectrum(nullptr),
m_specMax(0.0f),
@ -121,6 +124,10 @@ void SpectrumVis::feed(const Complex *begin, unsigned int length)
Complex c;
Real v;
int fftMin = (m_frequencyZoomFactor == 1.0f) ?
0 : (m_frequencyZoomPos - (0.5f / m_frequencyZoomFactor)) * m_settings.m_fftSize;
int fftMax = (m_frequencyZoomFactor == 1.0f) ?
m_settings.m_fftSize : (m_frequencyZoomPos - (0.5f / m_frequencyZoomFactor)) * m_settings.m_fftSize;
if (m_settings.m_averagingMode == GLSpectrumSettings::AvgModeNone)
{
@ -140,7 +147,7 @@ void SpectrumVis::feed(const Complex *begin, unsigned int length)
// send new data to visualisation
if (m_glSpectrum) {
m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize);
m_glSpectrum->newSpectrum(m_powerSpectrum.data(), m_settings.m_fftSize);
}
// web socket spectrum connections
@ -176,7 +183,7 @@ void SpectrumVis::feed(const Complex *begin, unsigned int length)
// send new data to visualisation
if (m_glSpectrum) {
m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize);
m_glSpectrum->newSpectrum(m_powerSpectrum.data(), m_settings.m_fftSize);
}
// web socket spectrum connections
@ -223,7 +230,7 @@ void SpectrumVis::feed(const Complex *begin, unsigned int length)
{
// send new data to visualisation
if (m_glSpectrum) {
m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize);
m_glSpectrum->newSpectrum(m_powerSpectrum.data(), m_settings.m_fftSize);
}
// web socket spectrum connections
@ -269,7 +276,7 @@ void SpectrumVis::feed(const Complex *begin, unsigned int length)
{
// send new data to visualisation
if (m_glSpectrum) {
m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize);
m_glSpectrum->newSpectrum(m_powerSpectrum.data(), m_settings.m_fftSize);
}
// web socket spectrum connections
@ -374,7 +381,7 @@ void SpectrumVis::feed(const SampleVector::const_iterator& cbegin, const SampleV
// send new data to visualisation
if (m_glSpectrum) {
m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize);
m_glSpectrum->newSpectrum(m_powerSpectrum.data(), m_settings.m_fftSize);
}
// web socket spectrum connections
@ -433,7 +440,7 @@ void SpectrumVis::feed(const SampleVector::const_iterator& cbegin, const SampleV
// send new data to visualisation
if (m_glSpectrum) {
m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize);
m_glSpectrum->newSpectrum(m_powerSpectrum.data(), m_settings.m_fftSize);
}
// web socket spectrum connections
@ -512,7 +519,7 @@ void SpectrumVis::feed(const SampleVector::const_iterator& cbegin, const SampleV
// send new data to visualisation
if (m_glSpectrum) {
m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize);
m_glSpectrum->newSpectrum(m_powerSpectrum.data(), m_settings.m_fftSize);
}
// web socket spectrum connections
@ -590,7 +597,7 @@ void SpectrumVis::feed(const SampleVector::const_iterator& cbegin, const SampleV
// send new data to visualisation
if (m_glSpectrum) {
m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize);
m_glSpectrum->newSpectrum(m_powerSpectrum.data(), m_settings.m_fftSize);
}
// web socket spectrum connections
@ -694,7 +701,13 @@ bool SpectrumVis::handleMessage(const Message& message)
{
MsgStartStop& cmd = (MsgStartStop&) message;
setRunning(cmd.getStartStop());
return true;
}
else if (MsgFrequencyZooming::match(message))
{
MsgFrequencyZooming& cmd = (MsgFrequencyZooming&) message;
m_frequencyZoomFactor = cmd.getFrequencyZoomFactor();
m_frequencyZoomPos = cmd.getFrequencyZoomPos();
return true;
}
else

View File

@ -107,6 +107,28 @@ public:
{}
};
class MsgFrequencyZooming : public Message {
MESSAGE_CLASS_DECLARATION
public:
float getFrequencyZoomFactor() const { return m_frequencyZoomFactor; }
float getFrequencyZoomPos() const { return m_frequencyZoomPos; }
static MsgFrequencyZooming* create(float frequencyZoomFactor, float frequencyZoomPos) {
return new MsgFrequencyZooming(frequencyZoomFactor, frequencyZoomPos);
}
private:
float m_frequencyZoomFactor;
float m_frequencyZoomPos;
MsgFrequencyZooming(float frequencyZoomFactor, float frequencyZoomPos) :
Message(),
m_frequencyZoomFactor(frequencyZoomFactor),
m_frequencyZoomPos(frequencyZoomPos)
{ }
};
enum AvgMode
{
AvgModeNone,
@ -198,6 +220,9 @@ private:
int m_fftBufferFill;
bool m_needMoreSamples;
float m_frequencyZoomFactor;
float m_frequencyZoomPos;
Real m_scalef;
GLSpectrumInterface* m_glSpectrum;
WSSpectrum m_wsSpectrum;

View File

@ -25,6 +25,7 @@
#include <QOpenGLFunctions>
#include <QPainter>
#include <QFontDatabase>
#include "dsp/spectrumvis.h"
#include "gui/glspectrum.h"
#include "util/messagequeue.h"
@ -33,10 +34,13 @@
MESSAGE_CLASS_DEFINITION(GLSpectrum::MsgReportSampleRate, Message)
MESSAGE_CLASS_DEFINITION(GLSpectrum::MsgReportWaterfallShare, Message)
const float GLSpectrum::m_maxFrequencyZoom = 4.0f;
GLSpectrum::GLSpectrum(QWidget* parent) :
QGLWidget(parent),
m_cursorState(CSNormal),
m_cursorChannel(0),
m_spectrumVis(nullptr),
m_fpsPeriodMs(50),
m_mouseInside(false),
m_changesPending(true),
@ -159,6 +163,7 @@ GLSpectrum::GLSpectrum(QWidget* parent) :
m_textOverlayFont = font(); // QFontDatabase::systemFont(QFontDatabase::FixedFont);
m_textOverlayFont.setBold(true);
// m_textOverlayFont.setPointSize(font().pointSize() - 1);
resetFrequencyZoom();
m_timer.setTimerType(Qt::PreciseTimer);
connect(&m_timer, SIGNAL(timeout()), this, SLOT(tick()));
@ -408,7 +413,7 @@ void GLSpectrum::removeChannelMarker(ChannelMarker* channelMarker)
m_mutex.unlock();
}
void GLSpectrum::newSpectrum(const std::vector<Real>& spectrum, int fftSize)
void GLSpectrum::newSpectrum(const Real *spectrum, int fftSize)
{
QMutexLocker mutexLocker(&m_mutex);
@ -435,7 +440,7 @@ void GLSpectrum::newSpectrum(const std::vector<Real>& spectrum, int fftSize)
}
}
void GLSpectrum::updateWaterfall(const std::vector<Real>& spectrum)
void GLSpectrum::updateWaterfall(const Real *spectrum)
{
if (m_waterfallBufferPos < m_waterfallBuffer->height())
{
@ -458,7 +463,7 @@ void GLSpectrum::updateWaterfall(const std::vector<Real>& spectrum)
}
}
void GLSpectrum::updateHistogram(const std::vector<Real>& spectrum)
void GLSpectrum::updateHistogram(const Real *spectrum)
{
quint8* b = m_histogram;
int fftMulSize = 100 * m_fftSize;
@ -484,7 +489,7 @@ void GLSpectrum::updateHistogram(const std::vector<Real>& spectrum)
}
}
m_currentSpectrum = &spectrum; // Store spectrum for current spectrum line display
m_currentSpectrum = spectrum; // Store spectrum for current spectrum line display
#if 0 //def USE_SSE2
if(m_decay >= 0) { // normal
@ -963,7 +968,7 @@ void GLSpectrum::paintGL()
for (int i = 0; i < m_fftSize; i++)
{
Real v = (*m_currentSpectrum)[i] - m_referenceLevel;
Real v = m_currentSpectrum[i] - m_referenceLevel;
if (v > 0) {
v = 0;
@ -2193,16 +2198,73 @@ void GLSpectrum::mouseReleaseEvent(QMouseEvent*)
void GLSpectrum::wheelEvent(QWheelEvent *event)
{
int mul;
if (event->modifiers() & Qt::ShiftModifier) {
mul = 100;
channelMarkerMove(event, 100);
} else if (event->modifiers() & Qt::ControlModifier) {
mul = 10;
channelMarkerMove(event, 10);
} else if (event->modifiers() & Qt::AltModifier) {
frequencyZoom(event);
} else {
mul = 1;
channelMarkerMove(event, 1);
}
}
void GLSpectrum::frequencyZoom(QWheelEvent *event)
{
const QPointF& p = event->position();
if (event->delta() > 0) // zoom in
{
if (m_frequencyZoomFactor < m_maxFrequencyZoom) {
m_frequencyZoomFactor += 0.5f;
}
}
else
{
if (m_frequencyZoomFactor > 1.0f) {
m_frequencyZoomFactor -= 0.5f;
}
}
float pw = (p.x() - m_leftMargin) / (width() - m_leftMargin - m_rightMargin); // position in window
pw = pw < 0.0f ? 0.0f : pw > 1.0f ? 1.0 : pw;
m_frequencyZoomPos += (pw - 0.5f) * (1.0f / m_frequencyZoomFactor);
float lim = 0.5f / m_frequencyZoomFactor;
m_frequencyZoomPos = m_frequencyZoomPos < lim ? lim : m_frequencyZoomPos > 1 - lim ? 1 - lim : m_frequencyZoomPos;
updateFFTLimits();
qDebug("GLSpectrum::spectrumZoom: pw: %f p: %f z: %f", pw, m_frequencyZoomPos, m_frequencyZoomFactor);
}
void GLSpectrum::resetFrequencyZoom()
{
m_frequencyZoomFactor = 1.0f;
m_frequencyZoomPos = 0.5f;
updateFFTLimits();
}
void GLSpectrum::updateFFTLimits()
{
if (!m_spectrumVis) {
return;
}
SpectrumVis::MsgFrequencyZooming *msg = SpectrumVis::MsgFrequencyZooming::create(
m_frequencyZoomFactor, m_frequencyZoomPos
);
m_spectrumVis->getInputMessageQueue()->push(msg);
}
// void GLSpectrum::updateFFTLimits()
// {
// m_fftMin = m_frequencyZoomFactor == 1 ? 0 : (m_frequencyZoomPos - (0.5f / m_frequencyZoomFactor)) * m_fftSize;
// m_fftMax = m_frequencyZoomFactor == 1 ? m_fftSize : (m_frequencyZoomPos - (0.5f / m_frequencyZoomFactor)) * m_fftSize;
// }
void GLSpectrum::channelMarkerMove(QWheelEvent *event, int mul)
{
for (int i = 0; i < m_channelMarkerStates.size(); ++i)
{
if ((m_channelMarkerStates[i]->m_channelMarker->getSourceOrSinkStream() != m_displaySourceOrSink)

View File

@ -39,6 +39,7 @@
class QOpenGLShaderProgram;
class MessageQueue;
class SpectrumVis;
class SDRGUI_API GLSpectrum : public QGLWidget, public GLSpectrumInterface {
Q_OBJECT
@ -103,7 +104,7 @@ public:
void removeChannelMarker(ChannelMarker* channelMarker);
void setMessageQueueToGUI(MessageQueue* messageQueue) { m_messageQueueToGUI = messageQueue; }
virtual void newSpectrum(const std::vector<Real>& spectrum, int fftSize);
virtual void newSpectrum(const Real* spectrum, int fftSize);
void clearSpectrumHistogram();
Real getWaterfallShare() const { return m_waterfallShare; }
@ -115,6 +116,7 @@ public:
m_displaySourceOrSink = sourceOrSink;
m_displayStreamIndex = streamIndex;
}
void setSpectrumVis(SpectrumVis *spectrumVis) { m_spectrumVis = spectrumVis; }
private:
struct ChannelMarkerState {
@ -235,6 +237,7 @@ private:
CursorState m_cursorState;
int m_cursorChannel;
SpectrumVis* m_spectrumVis;
QTimer m_timer;
int m_fpsPeriodMs;
QMutex m_mutex;
@ -259,7 +262,7 @@ private:
std::vector<Real> m_maxHold;
bool m_displayMaxHold;
const std::vector<Real> *m_currentSpectrum;
const Real *m_currentSpectrum;
bool m_displayCurrent;
Real m_waterfallShare;
@ -305,6 +308,9 @@ private:
bool m_displayChanged;
bool m_displaySourceOrSink;
int m_displayStreamIndex;
float m_frequencyZoomFactor;
float m_frequencyZoomPos;
static const float m_maxFrequencyZoom;
GLShaderSimple m_glShaderSimple;
GLShaderTextured m_glShaderLeftScale;
@ -321,10 +327,8 @@ private:
MessageQueue *m_messageQueueToGUI;
static const int m_waterfallBufferHeight = 256;
void updateWaterfall(const std::vector<Real>& spectrum);
void updateHistogram(const std::vector<Real>& spectrum);
void updateWaterfall(const Real *spectrum);
void updateHistogram(const Real *spectrum);
void initializeGL();
void resizeGL(int width, int height);
@ -338,6 +342,10 @@ private:
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void wheelEvent(QWheelEvent*);
void channelMarkerMove(QWheelEvent*, int mul);
void frequencyZoom(QWheelEvent*);
void resetFrequencyZoom();
void updateFFTLimits();
void enterEvent(QEvent* event);
void leaveEvent(QEvent* event);

View File

@ -77,6 +77,7 @@ void GLSpectrumGUI::setBuddies(SpectrumVis* spectrumVis, GLSpectrum* glSpectrum)
{
m_spectrumVis = spectrumVis;
m_glSpectrum = glSpectrum;
m_glSpectrum->setSpectrumVis(spectrumVis);
m_glSpectrum->setMessageQueueToGUI(&m_messageQueue);
m_spectrumVis->setMessageQueueToGUI(&m_messageQueue);
}