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
27 changes: 19 additions & 8 deletions src/inputsource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <QJsonObject>
#include <QJsonArray>
#include <QFile>
#include <QColor>


class ComplexF32SampleAdapter : public SampleAdapter {
Expand Down Expand Up @@ -264,7 +265,9 @@ void InputSource::readMetaData(const QString &filename)


auto datatype = global["core:datatype"].toString();
if (datatype.compare("cf32_le") == 0) {
if (datatype.compare("cf64_le") == 0) {
sampleAdapter = std::make_unique<ComplexF64SampleAdapter>();
} else if (datatype.compare("cf32_le") == 0) {
sampleAdapter = std::make_unique<ComplexF32SampleAdapter>();
} else if (datatype.compare("ci32_le") == 0) {
sampleAdapter = std::make_unique<ComplexS32SampleAdapter>();
Expand Down Expand Up @@ -339,10 +342,23 @@ void InputSource::readMetaData(const QString &filename)
auto frequencyRange = range_t<double>{freq_lower_edge, freq_upper_edge};

auto label = sigmf_annotation["core:label"].toString();
if (label.isEmpty()) {
label = sigmf_annotation["core:description"].toString();
}

auto comment = sigmf_annotation["core:comment"].toString();

annotationList.emplace_back(sampleRange, frequencyRange, label, comment);
auto sigmf_color = sigmf_annotation["presentation:color"].toString();
// SigMF uses the format "#RRGGBBAA" for alpha-channel colors, QT uses "#AARRGGBB"
if ((sigmf_color.at(0) == '#') && (sigmf_color.length()) == 9) {
sigmf_color = "#" + sigmf_color.mid(7,2) + sigmf_color.mid(1,6);
}
auto boxColor = QString::fromStdString("white");
if (QColor::isValidColor(sigmf_color)) {
boxColor = sigmf_color;
}

annotationList.emplace_back(sampleRange, frequencyRange, label, comment, boxColor);
}
}
}
Expand Down Expand Up @@ -397,13 +413,8 @@ void InputSource::openFile(const char *filename)
annotationList.clear();
QString metaFilename;

if (suffix == "sigmf-meta") {
if (suffix == "sigmf-meta" || suffix == "sigmf-data" || suffix == "sigmf-") {
dataFilename = fileInfo.path() + "/" + fileInfo.completeBaseName() + ".sigmf-data";
metaFilename = filename;
readMetaData(metaFilename);
}
else if (suffix == "sigmf-data") {
dataFilename = filename;
metaFilename = fileInfo.path() + "/" + fileInfo.completeBaseName() + ".sigmf-meta";
readMetaData(metaFilename);
}
Expand Down
2 changes: 2 additions & 0 deletions src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ MainWindow::MainWindow()
connect(dock->scalesCheckBox, &QCheckBox::stateChanged, plots, &PlotView::enableScales);
connect(dock->annosCheckBox, &QCheckBox::stateChanged, plots, &PlotView::enableAnnotations);
connect(dock->annosCheckBox, &QCheckBox::stateChanged, dock, &SpectrogramControls::enableAnnotations);
connect(dock->annoLabelCheckBox, &QCheckBox::stateChanged, plots, &PlotView::enableAnnoLabels);
connect(dock->commentsCheckBox, &QCheckBox::stateChanged, plots, &PlotView::enableAnnotationCommentsTooltips);
connect(dock->annoColorCheckBox, &QCheckBox::stateChanged, plots, &PlotView::enableAnnoColors);
connect(dock->cursorSymbolsSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), plots, &PlotView::setCursorSegments);

// Connect dock outputs
Expand Down
38 changes: 34 additions & 4 deletions src/plotview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ PlotView::PlotView(InputSource *input) : cursors(this), viewRange({0, 0})
enableScales(true);

enableAnnotations(true);
enableAnnoLabels(true);
enableAnnoColors(true);
enableAnnotationCommentsTooltips(true);

addPlot(spectrogramPlot);
Expand Down Expand Up @@ -425,29 +427,40 @@ void PlotView::setCursorSegments(int segments)
selectedSamples.maximum = selectedSamples.minimum + (segments * sampPerSeg + 0.5f);

cursors.setSegments(segments);

updateView();
emitTimeSelection();
}

void PlotView::setFFTAndZoom(int size, int zoom)
{
auto oldSamplesPerColumn = samplesPerColumn();
float oldPlotCenter = (verticalScrollBar()->value() + viewport()->height() / 2.0) / plotsHeight();
if (verticalScrollBar()->maximum() == 0)
oldPlotCenter = 0.5;

// Set new FFT size
fftSize = size;
if (spectrogramPlot != nullptr)
spectrogramPlot->setFFTSize(size);

// Set new zoom level
zoomLevel = zoom;
if (spectrogramPlot != nullptr)
spectrogramPlot->setZoomLevel(zoom);
zoomLevel = std::max(1,zoom);
nfftSkip = std::max(1,-1*zoom);
if (spectrogramPlot != nullptr) {
spectrogramPlot->setZoomLevel(zoomLevel);
spectrogramPlot->setSkip(nfftSkip);
}

// Update horizontal (time) scrollbar
horizontalScrollBar()->setSingleStep(10);
horizontalScrollBar()->setPageStep(100);

updateView(true, samplesPerColumn() < oldSamplesPerColumn);

// maintain the relative position of the vertical scroll bar
if (verticalScrollBar()->maximum())
verticalScrollBar()->setValue((int )(oldPlotCenter * plotsHeight() - viewport()->height() / 2.0 + 0.5f));
}

void PlotView::setPowerMin(int power)
Expand Down Expand Up @@ -568,7 +581,7 @@ void PlotView::resizeEvent(QResizeEvent * event)

size_t PlotView::samplesPerColumn()
{
return fftSize / zoomLevel;
return fftSize * nfftSkip / zoomLevel;
}

void PlotView::scrollContentsBy(int dx, int dy)
Expand Down Expand Up @@ -604,6 +617,7 @@ void PlotView::updateView(bool reCenter, bool expanding)
}
horizontalScrollBar()->setMaximum(std::max(0, sampleToColumn(mainSampleSource->count()) - width()));
verticalScrollBar()->setMaximum(std::max(0, plotsHeight() - viewport()->height()));

if (expanding) {
updateViewRange(reCenter);
}
Expand Down Expand Up @@ -647,13 +661,29 @@ void PlotView::enableAnnotations(bool enabled)
viewport()->update();
}

void PlotView::enableAnnoLabels(bool enabled)
{
if (spectrogramPlot != nullptr)
spectrogramPlot->enableAnnoLabels(enabled);

viewport()->update();
}

void PlotView::enableAnnotationCommentsTooltips(bool enabled)
{
annotationCommentsEnabled = enabled;

viewport()->update();
}

void PlotView::enableAnnoColors(bool enabled)
{
if (spectrogramPlot != nullptr)
spectrogramPlot->enableAnnoColors(enabled);

viewport()->update();
}

int PlotView::sampleToColumn(size_t sample)
{
return sample / samplesPerColumn();
Expand Down
3 changes: 3 additions & 0 deletions src/plotview.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ public slots:
void enableCursors(bool enabled);
void enableScales(bool enabled);
void enableAnnotations(bool enabled);
void enableAnnoLabels(bool enabled);
void enableAnnotationCommentsTooltips(bool enabled);
void enableAnnoColors(bool enabled);
void invalidateEvent() override;
void repaint();
void setCursorSegments(int segments);
Expand Down Expand Up @@ -77,6 +79,7 @@ public slots:

int fftSize = 1024;
int zoomLevel = 1;
int nfftSkip = 1;
int powerMin;
int powerMax;
bool cursorsEnabled;
Expand Down
6 changes: 4 additions & 2 deletions src/samplesource.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "util.h"
#include <QString>
#include <QObject>
#include <QColor>

class Annotation
{
Expand All @@ -34,11 +35,12 @@ class Annotation
range_t<double> frequencyRange;
QString label;
QString comment;
QColor boxColor;

Annotation(range_t<size_t> sampleRange, range_t<double>frequencyRange, QString label,
QString comment)
QString comment, QColor boxColor)
: sampleRange(sampleRange), frequencyRange(frequencyRange), label(label),
comment(comment) {}
comment(comment), boxColor(boxColor) {}
};

template<typename T>
Expand Down
21 changes: 16 additions & 5 deletions src/spectrogramcontrols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ SpectrogramControls::SpectrogramControls(const QString & title, QWidget * parent
layout->addRow(new QLabel(tr("<b>Spectrogram</b>")));

fftSizeSlider = new QSlider(Qt::Horizontal, widget);
fftSizeSlider->setRange(4, 13);
fftSizeSlider->setRange(4, 16);
fftSizeSlider->setPageStep(1);

layout->addRow(new QLabel(tr("FFT size:")), fftSizeSlider);

zoomLevelSlider = new QSlider(Qt::Horizontal, widget);
zoomLevelSlider->setRange(0, 10);
zoomLevelSlider->setRange(-6, 10);
zoomLevelSlider->setPageStep(1);

layout->addRow(new QLabel(tr("Zoom:")), zoomLevelSlider);
Expand Down Expand Up @@ -99,8 +99,12 @@ SpectrogramControls::SpectrogramControls(const QString & title, QWidget * parent

annosCheckBox = new QCheckBox(widget);
layout->addRow(new QLabel(tr("Display Annotations:")), annosCheckBox);
annoLabelCheckBox = new QCheckBox(widget);
layout->addRow(new QLabel(tr("Annotation Labels:")), annoLabelCheckBox);
commentsCheckBox = new QCheckBox(widget);
layout->addRow(new QLabel(tr("Display annotation comments tooltips:")), commentsCheckBox);
layout->addRow(new QLabel(tr("Annotation comments:")), commentsCheckBox);
annoColorCheckBox = new QCheckBox(widget);
layout->addRow(new QLabel(tr("Annotation Colors:")), annoColorCheckBox);

widget->setLayout(layout);
setWidget(widget);
Expand Down Expand Up @@ -136,7 +140,8 @@ void SpectrogramControls::setDefaults()
cursorSymbolsSpinBox->setValue(1);

annosCheckBox->setCheckState(Qt::Checked);
commentsCheckBox->setCheckState(Qt::Checked);
annoLabelCheckBox->setCheckState(Qt::Checked);
annoColorCheckBox->setCheckState(Qt::Checked);

// Try to set the sample rate from the last-used value
QSettings settings;
Expand All @@ -151,7 +156,13 @@ void SpectrogramControls::setDefaults()
void SpectrogramControls::fftOrZoomChanged(void)
{
int fftSize = pow(2, fftSizeSlider->value());
int zoomLevel = std::min(fftSize, (int)pow(2, zoomLevelSlider->value()));
int zoomLevel = zoomLevelSlider->value();
if (zoomLevel >= 0)
// zooming in by power-of-two steps
zoomLevel = std::min(fftSize, (int)pow(2, zoomLevel));
else
// zooming out (skipping FFTs) by power-of-two steps
zoomLevel = -1*std::min(fftSize, (int)pow(2, -1*zoomLevel));
emit fftOrZoomChanged(fftSize, zoomLevel);
}

Expand Down
2 changes: 2 additions & 0 deletions src/spectrogramcontrols.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,7 @@ private slots:
QLabel *symbolPeriodLabel;
QCheckBox *scalesCheckBox;
QCheckBox *annosCheckBox;
QCheckBox *annoLabelCheckBox;
QCheckBox *commentsCheckBox;
QCheckBox *annoColorCheckBox;
};
37 changes: 30 additions & 7 deletions src/spectrogramplot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ SpectrogramPlot::SpectrogramPlot(std::shared_ptr<SampleSource<std::complex<float
{
setFFTSize(fftSize);
zoomLevel = 1;
nfftSkip = 1;
powerMax = 0.0f;
powerMin = -50.0f;
sampleRate = 0;
frequencyScaleEnabled = false;
sigmfAnnotationsEnabled = true;
sigmfAnnotationLabels = true;
sigmfAnnotationColors = true;

for (int i = 0; i < 256; i++) {
float p = (float)i / 256;
Expand Down Expand Up @@ -194,8 +197,13 @@ void SpectrogramPlot::paintAnnotations(QPainter &painter, QRect &rect, range_t<s
int height = (a.frequencyRange.maximum - a.frequencyRange.minimum) / sampleRate * rect.height();
int width = (a.sampleRange.maximum - a.sampleRange.minimum) / getStride();

// Draw the label 2 pixels above the box
painter.drawText(x, y - 2, a.label);
if (sigmfAnnotationColors) {
painter.setPen(a.boxColor);
}
if (sigmfAnnotationLabels) {
// Draw the label 2 pixels above the box
painter.drawText(x, y - 2, a.label);
}
painter.drawRect(x, y, width, height);

visibleAnnotationLocations.emplace_back(a, x, y, width, height);
Expand Down Expand Up @@ -242,7 +250,7 @@ void SpectrogramPlot::paintMid(QPainter &painter, QRect &rect, range_t<size_t> s

QPixmap* SpectrogramPlot::getPixmapTile(size_t tile)
{
QPixmap *obj = pixmapCache.object(TileCacheKey(fftSize, zoomLevel, tile));
QPixmap *obj = pixmapCache.object(TileCacheKey(fftSize, zoomLevel, nfftSkip, tile));
if (obj != 0)
return obj;

Expand All @@ -261,13 +269,13 @@ QPixmap* SpectrogramPlot::getPixmapTile(size_t tile)
}
}
obj->convertFromImage(image);
pixmapCache.insert(TileCacheKey(fftSize, zoomLevel, tile), obj);
pixmapCache.insert(TileCacheKey(fftSize, zoomLevel, nfftSkip, tile), obj);
return obj;
}

float* SpectrogramPlot::getFFTTile(size_t tile)
{
std::array<float, tileSize>* obj = fftCache.object(TileCacheKey(fftSize, zoomLevel, tile));
std::array<float, tileSize>* obj = fftCache.object(TileCacheKey(fftSize, zoomLevel, nfftSkip, tile));
if (obj != nullptr)
return obj->data();

Expand All @@ -279,7 +287,7 @@ float* SpectrogramPlot::getFFTTile(size_t tile)
sample += getStride();
ptr += fftSize;
}
fftCache.insert(TileCacheKey(fftSize, zoomLevel, tile), destStorage);
fftCache.insert(TileCacheKey(fftSize, zoomLevel, nfftSkip, tile), destStorage);
return destStorage->data();
}

Expand Down Expand Up @@ -316,7 +324,7 @@ void SpectrogramPlot::getLine(float *dest, size_t sample)

int SpectrogramPlot::getStride()
{
return fftSize / zoomLevel;
return fftSize * nfftSkip / zoomLevel;
}

float SpectrogramPlot::getTunerPhaseInc()
Expand Down Expand Up @@ -397,6 +405,11 @@ void SpectrogramPlot::setZoomLevel(int zoom)
zoomLevel = zoom;
}

void SpectrogramPlot::setSkip(int skip)
{
nfftSkip = skip;
}

void SpectrogramPlot::setSampleRate(double rate)
{
sampleRate = rate;
Expand All @@ -417,6 +430,16 @@ bool SpectrogramPlot::isAnnotationsEnabled(void)
return sigmfAnnotationsEnabled;
}

void SpectrogramPlot::enableAnnoLabels(bool enabled)
{
sigmfAnnotationLabels = enabled;
}

void SpectrogramPlot::enableAnnoColors(bool enabled)
{
sigmfAnnotationColors = enabled;
}

bool SpectrogramPlot::tunerEnabled()
{
return (tunerTransform->subscriberCount() > 0);
Expand Down
Loading