Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ MainWindow::MainWindow()
// Connect dock inputs
connect(dock, &SpectrogramControls::openFile, this, &MainWindow::openFile);
connect(dock->sampleRate, static_cast<void (QLineEdit::*)(const QString&)>(&QLineEdit::textChanged), this, static_cast<void (MainWindow::*)(QString)>(&MainWindow::setSampleRate));
connect(dock->timePointerCheckBox, &QCheckBox::stateChanged, plots, &PlotView::enableTimePointer);
connect(dock->frequencyPointerCheckBox, &QCheckBox::stateChanged, plots, &PlotView::enableFrequencyPointer);
connect(dock, static_cast<void (SpectrogramControls::*)(int, int)>(&SpectrogramControls::fftOrZoomChanged), plots, &PlotView::setFFTAndZoom);
connect(dock->powerMaxSlider, &QSlider::valueChanged, plots, &PlotView::setPowerMax);
connect(dock->powerMinSlider, &QSlider::valueChanged, plots, &PlotView::setPowerMin);
Expand Down
20 changes: 20 additions & 0 deletions src/plotview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ PlotView::PlotView(InputSource *input) : cursors(this), viewRange({0, 0})
auto tunerOutput = std::dynamic_pointer_cast<SampleSource<std::complex<float>>>(spectrogramPlot->output());

enableScales(true);
timePointerEnabled = false;
frequencyPointerEnabled = false;

enableAnnotations(true);
enableAnnotationCommentsTooltips(true);
Expand Down Expand Up @@ -223,6 +225,21 @@ void PlotView::enableCursors(bool enabled)
viewport()->update();
}

void PlotView::enableTimePointer(bool enabled)
{
timePointerEnabled = enabled;
spectrogramPlot->enableTimeFrequencyPointers(timePointerEnabled, frequencyPointerEnabled);

viewport()->update();
}

void PlotView::enableFrequencyPointer(bool enabled)
{
frequencyPointerEnabled = enabled;
spectrogramPlot->enableTimeFrequencyPointers(timePointerEnabled, frequencyPointerEnabled);

viewport()->update();
}
bool PlotView::viewportEvent(QEvent *event) {
// Handle wheel events for zooming (before the parent's handler to stop normal scrolling)
if (event->type() == QEvent::Wheel) {
Expand Down Expand Up @@ -286,6 +303,9 @@ bool PlotView::viewportEvent(QEvent *event) {
if (cursorsEnabled)
if (cursors.mouseEvent(event->type(), mouseEvent))
return true;

if (timePointerEnabled || frequencyPointerEnabled)
updateView();
}

if (event->type() == QEvent::Leave) {
Expand Down
4 changes: 4 additions & 0 deletions src/plotview.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class PlotView : public QGraphicsView, Subscriber

public slots:
void cursorsMoved();
void enableTimePointer(bool enabled);
void enableFrequencyPointer(bool enabled);
void enableCursors(bool enabled);
void enableScales(bool enabled);
void enableAnnotations(bool enabled);
Expand Down Expand Up @@ -79,6 +81,8 @@ public slots:
int zoomLevel = 1;
int powerMin;
int powerMax;
bool timePointerEnabled;
bool frequencyPointerEnabled;
bool cursorsEnabled;
double sampleRate = 0.0;
bool timeScaleEnabled;
Expand Down
6 changes: 6 additions & 0 deletions src/spectrogramcontrols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ SpectrogramControls::SpectrogramControls(const QString & title, QWidget * parent
sampleRate->setValidator(double_validator);
layout->addRow(new QLabel(tr("Sample rate:")), sampleRate);

// Frequency and time pointer settings
frequencyPointerCheckBox = new QCheckBox(widget);
layout->addRow(new QLabel(tr("Enable frequency pointer:")), frequencyPointerCheckBox);
timePointerCheckBox = new QCheckBox(widget);
layout->addRow(new QLabel(tr("Enable time pointer:")), timePointerCheckBox);

// Spectrogram settings
layout->addRow(new QLabel()); // TODO: find a better way to add an empty row?
layout->addRow(new QLabel(tr("<b>Spectrogram</b>")));
Expand Down
2 changes: 2 additions & 0 deletions src/spectrogramcontrols.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ private slots:
public:
QPushButton *fileOpenButton;
QLineEdit *sampleRate;
QCheckBox *timePointerCheckBox;
QCheckBox *frequencyPointerCheckBox;
QSlider *fftSizeSlider;
QSlider *zoomLevelSlider;
QSlider *powerMaxSlider;
Expand Down
60 changes: 60 additions & 0 deletions src/spectrogramplot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ SpectrogramPlot::SpectrogramPlot(std::shared_ptr<SampleSource<std::complex<float
sampleRate = 0;
frequencyScaleEnabled = false;
sigmfAnnotationsEnabled = true;
timePointerEnabled = false;
frequencyPointerEnabled = false;

for (int i = 0; i < 256; i++) {
float p = (float)i / 256;
Expand Down Expand Up @@ -72,6 +74,54 @@ void SpectrogramPlot::paintFront(QPainter &painter, QRect &rect, range_t<size_t>

if (sigmfAnnotationsEnabled)
paintAnnotations(painter, rect, sampleRange);

if (timePointerEnabled || frequencyPointerEnabled)
paintTimeFrequencyPointers(painter, rect, sampleRange);
}

void SpectrogramPlot::paintTimeFrequencyPointers(QPainter &painter, QRect &rect, range_t<size_t> sampleRange)
{
if (sampleRate == 0) {
return;
}

if (sampleRate / 2 > UINT64_MAX) {
return;
}

int plotHeight = rect.height();
if (inputSource->realSignal())
plotHeight *= 2;

double bwPerPixel = (double)sampleRate / plotHeight;

painter.save();

QPen pen(Qt::white, 1, Qt::SolidLine);
painter.setPen(pen);
QFontMetrics fm(painter.font());


char buf[128];
if (frequencyPointerEnabled) {
int freqHz = ((plotHeight / 2) - mouseY) * bwPerPixel;
snprintf(buf, sizeof(buf), "Frequency: %d Hz", freqHz);

painter.drawLine(0, mouseY, mouseX, mouseY);
painter.drawText(mouseX + 15, mouseY, buf);
}
if (timePointerEnabled) {
float timeStart = sampleRange.minimum / sampleRate;
float timeEnd = sampleRange.maximum / sampleRate;
float secondsPerPixel = (timeEnd - timeStart) / rect.width();
float timeAtPointer = timeStart + mouseX * secondsPerPixel;
snprintf(buf, sizeof(buf), "Time: %.6f s", timeAtPointer);

painter.drawText(mouseX + 15, mouseY + fm.height(), buf);
painter.drawLine(mouseX, 0, mouseX, mouseY);
}

painter.restore();
}

void SpectrogramPlot::paintFrequencyScale(QPainter &painter, QRect &rect)
Expand Down Expand Up @@ -356,6 +406,11 @@ bool SpectrogramPlot::mouseEvent(QEvent::Type type, QMouseEvent *event)
if (tunerEnabled())
return tuner.mouseEvent(type, event);

if (timePointerEnabled || frequencyPointerEnabled) {
mouseX = event->x();
mouseY = event->y();
}

return false;
}

Expand Down Expand Up @@ -448,6 +503,11 @@ void SpectrogramPlot::tunerMoved()
emit repaint();
}

void SpectrogramPlot::enableTimeFrequencyPointers(bool timePointer, bool frequencyPointer) {
timePointerEnabled = timePointer;
frequencyPointerEnabled = frequencyPointer;
}

uint qHash(const TileCacheKey &key, uint seed)
{
return key.fftSize ^ key.zoomLevel ^ key.sample ^ seed;
Expand Down
7 changes: 7 additions & 0 deletions src/spectrogramplot.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class SpectrogramPlot : public Plot
bool tunerEnabled();
void enableScales(bool enabled);
void enableAnnotations(bool enabled);
void enableTimeFrequencyPointers(bool timePointer, bool frequencyPointer);
bool isAnnotationsEnabled();
QString *mouseAnnotationComment(const QMouseEvent *event);

Expand Down Expand Up @@ -103,6 +104,11 @@ public slots:
double sampleRate;
bool frequencyScaleEnabled;
bool sigmfAnnotationsEnabled;
bool timePointerEnabled;
bool frequencyPointerEnabled;

int mouseX;
int mouseY;

Tuner tuner;
std::shared_ptr<TunerTransform> tunerTransform;
Expand All @@ -116,6 +122,7 @@ public slots:
int linesPerTile();
void paintFrequencyScale(QPainter &painter, QRect &rect);
void paintAnnotations(QPainter &painter, QRect &rect, range_t<size_t> sampleRange);
void paintTimeFrequencyPointers(QPainter &painter, QRect &rect, range_t<size_t> sampleRange);
};

class AnnotationLocation
Expand Down