diff --git a/mainwindow.cpp b/mainwindow.cpp index 3e2d809..1d67801 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -49,6 +49,13 @@ MainWindow::MainWindow() connect(dock->powerMinSlider, SIGNAL(valueChanged(int)), &spectrogram, SLOT(setPowerMin(int))); connect(scrollArea.verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(spectrogramSliderMoved(int))); + + connect(dock->timeScaleCheckBox, SIGNAL(stateChanged(int)), &spectrogram, SLOT(setTimeScaleEnable(int))); + connect(&spectrogram, SIGNAL(cursorFrequencyChanged(QString)), dock->cursorFrequencyLabel, SLOT(setText(QString))); + connect(&spectrogram, SIGNAL(cursorTimeChanged(QString)), dock->cursorTimeLabel, SLOT(setText(QString))); + connect(dock->deltaDragCheckBox, SIGNAL(stateChanged(int)), &spectrogram, SLOT(setDeltaDragEnable(int))); + connect(&spectrogram, SIGNAL(deltaFrequencyChanged(QString)), dock->deltaFrequencyLabel, SLOT(setText(QString))); + connect(&spectrogram, SIGNAL(deltaTimeChanged(QString)), dock->deltaTimeLabel, SLOT(setText(QString))); } QRubberBand *rubberBand=NULL; diff --git a/spectrogram.cpp b/spectrogram.cpp index 020f8a0..b9df358 100644 --- a/spectrogram.cpp +++ b/spectrogram.cpp @@ -36,11 +36,15 @@ Spectrogram::Spectrogram() zoomLevel = 0; powerMax = 0.0f; powerMin = -50.0f; + timeScaleIsEnabled = true; + deltaDragIsEnabled = true; for (int i = 0; i < 256; i++) { float p = (float)i / 256; colormap[i] = QColor::fromHsvF(p * 0.83f, 1.0, 1.0 - p).rgba(); } + + setMouseTracking(true); } Spectrogram::~Spectrogram() @@ -70,6 +74,48 @@ void Spectrogram::openFile(QString fileName) } } +void Spectrogram::xyToFreqTime(int x, int y, float *freq, float *time) +{ + *freq = labs(x - (fftSize / 2)) * sampleRate / 2 / (float)fftSize; + *time = (float)lineToSample(y) / sampleRate; +} + +void Spectrogram::mouseReleaseEvent(QMouseEvent *event) +{ + if (deltaDragIsEnabled) { + cursorStartX = -1; + update(); + } +} + +void Spectrogram::mouseMoveEvent(QMouseEvent *event) +{ + float freq, time; + xyToFreqTime(event->x(), event->y(), &freq, &time); + emit cursorFrequencyChanged(QString::number(freq) + " Hz"); + emit cursorTimeChanged(QString::number(time) + " s"); + if (cursorStartX != -1) { + float s_freq, s_time; + xyToFreqTime(cursorStartX, cursorStartY, &s_freq, &s_time); + emit deltaFrequencyChanged(QString::number(fabs(s_freq - freq)) + " Hz"); + emit deltaTimeChanged(QString::number(fabs(s_time - time)) + " s"); + cursorEndX = event->x(); + cursorEndY = event->y(); + update(); + } +} + +void Spectrogram::mousePressEvent(QMouseEvent *event) +{ + if (cursorStartX == -1) { + cursorEndX = cursorStartX = event->x(); + cursorEndY = cursorStartY = event->y(); + } else { + cursorStartX = -1; + } + update(); +} + void Spectrogram::paintEvent(QPaintEvent *event) { QRect rect = event->rect(); @@ -93,6 +139,7 @@ void Spectrogram::paintEvent(QPaintEvent *event) } paintTimeAxis(&painter, rect); + paintCursors(&painter, rect); } } @@ -161,22 +208,39 @@ void Spectrogram::getLine(float *dest, off_t sample) } } +void Spectrogram::paintCursors(QPainter *painter, QRect rect) +{ + if (cursorStartX != -1) { + painter->save(); + QPen pen(Qt::white, 1, Qt::DashLine); + painter->setPen(pen); + painter->drawLine(rect.left(), cursorStartY, rect.right(), cursorStartY); + painter->drawLine(cursorStartX, rect.top(), cursorStartX, rect.bottom()); + painter->drawLine(rect.left(), cursorEndY, rect.right(), cursorEndY); + painter->drawLine(cursorEndX, rect.top(), cursorEndX, rect.bottom()); + painter->restore(); + + } +} + void Spectrogram::paintTimeAxis(QPainter *painter, QRect rect) { - // Round up for firstLine and round each to nearest linesPerGraduation - int firstLine = ((rect.y() + linesPerGraduation - 1) / linesPerGraduation) * linesPerGraduation; - int lastLine = ((rect.y() + rect.height()) / linesPerGraduation) * linesPerGraduation; + if (timeScaleIsEnabled) { + // Round up for firstLine and round each to nearest linesPerGraduation + int firstLine = ((rect.y() + linesPerGraduation - 1) / linesPerGraduation) * linesPerGraduation; + int lastLine = ((rect.y() + rect.height()) / linesPerGraduation) * linesPerGraduation; - painter->save(); - QPen pen(Qt::white, 1, Qt::SolidLine); - painter->setPen(pen); - QFontMetrics fm(painter->font()); - int textOffset = fm.ascent() / 2 - 1; - for (int line = firstLine; line <= lastLine; line += linesPerGraduation) { - painter->drawLine(0, line, 10, line); - painter->drawText(12, line + textOffset, sampleToTime(lineToSample(line))); + painter->save(); + QPen pen(Qt::white, 1, Qt::SolidLine); + painter->setPen(pen); + QFontMetrics fm(painter->font()); + int textOffset = fm.ascent() / 2 - 1; + for (int line = firstLine; line <= lastLine; line += linesPerGraduation) { + painter->drawLine(0, line, 10, line); + painter->drawText(12, line + textOffset, sampleToTime(lineToSample(line))); + } + painter->restore(); } - painter->restore(); } void Spectrogram::setSampleRate(int rate) @@ -219,6 +283,19 @@ void Spectrogram::setZoomLevel(int zoom) resize(fftSize, getHeight()); } +void Spectrogram::setTimeScaleEnable(int state) +{ + timeScaleIsEnabled = (state == Qt::Checked); + pixmapCache.clear(); + update(); +} + +void Spectrogram::setDeltaDragEnable(int state) +{ + deltaDragIsEnabled = (state == Qt::Checked); +} + + int Spectrogram::getHeight() { if (!inputSource) diff --git a/spectrogram.h b/spectrogram.h index 8de6b12..c52b936 100644 --- a/spectrogram.h +++ b/spectrogram.h @@ -44,6 +44,13 @@ public: off_t lineToSample(off_t line); InputSource *inputSource = nullptr; + +signals: + void cursorFrequencyChanged(QString); + void cursorTimeChanged(QString); + void deltaFrequencyChanged(QString); + void deltaTimeChanged(QString); + public slots: void openFile(QString fileName); void setSampleRate(int rate); @@ -51,9 +58,14 @@ public slots: void setPowerMax(int power); void setPowerMin(int power); void setZoomLevel(int zoom); + void setTimeScaleEnable(int state); + void setDeltaDragEnable(int state); protected: void paintEvent(QPaintEvent *event); + void mouseReleaseEvent(QMouseEvent * event); + void mouseMoveEvent(QMouseEvent * event); + void mousePressEvent(QMouseEvent * event); private: @@ -72,14 +84,20 @@ private: int zoomLevel; float powerMax; float powerMin; + bool timeScaleIsEnabled; + bool deltaDragIsEnabled; + int cursorStartX = -1, cursorStartY; + int cursorEndX, cursorEndY; QPixmap* getPixmapTile(off_t tile); float* getFFTTile(off_t tile); void getLine(float *dest, off_t sample); void paintTimeAxis(QPainter *painter, QRect rect); + void paintCursors(QPainter *painter, QRect rect); int sampleToLine(off_t sample); QString sampleToTime(off_t sample); int linesPerTile(); + void xyToFreqTime(int x, int y, float *freq, float *time); }; class TileCacheKey diff --git a/spectrogramcontrols.cpp b/spectrogramcontrols.cpp index bfd75fc..3c8197f 100644 --- a/spectrogramcontrols.cpp +++ b/spectrogramcontrols.cpp @@ -56,6 +56,26 @@ SpectrogramControls::SpectrogramControls(const QString & title, QWidget * parent powerMinSlider->setValue(-50); layout->addRow(new QLabel(tr("Power min:")), powerMinSlider); + timeScaleCheckBox = new QCheckBox(widget); + timeScaleCheckBox->setCheckState(Qt::Checked); + layout->addRow(new QLabel(tr("time overlay:")), timeScaleCheckBox); + + cursorFrequencyLabel = new QLabel(); + layout->addRow(new QLabel(tr("Cursor frequency:")), cursorFrequencyLabel); + + cursorTimeLabel = new QLabel(); + layout->addRow(new QLabel(tr("Cursor time:")), cursorTimeLabel); + + deltaDragCheckBox = new QCheckBox(widget); + deltaDragCheckBox->setCheckState(Qt::Checked); + layout->addRow(new QLabel(tr("Delta dragging:")), deltaDragCheckBox); + + deltaFrequencyLabel = new QLabel(); + layout->addRow(new QLabel(tr("Delta frequency:")), deltaFrequencyLabel); + + deltaTimeLabel = new QLabel(); + layout->addRow(new QLabel(tr("Delta time:")), deltaTimeLabel); + widget->setLayout(layout); setWidget(widget); @@ -74,4 +94,4 @@ void SpectrogramControls::fileOpenButtonClicked() this, tr("Open File"), "", tr("Sample file (*.cfile *.bin);;All files (*)") ); emit openFile(fileName); -} \ No newline at end of file +} diff --git a/spectrogramcontrols.h b/spectrogramcontrols.h index 1979378..943deb5 100644 --- a/spectrogramcontrols.h +++ b/spectrogramcontrols.h @@ -24,6 +24,8 @@ #include #include #include +#include +#include class SpectrogramControls : public QDockWidget { @@ -50,4 +52,10 @@ public: QSlider *zoomLevelSlider; QSlider *powerMaxSlider; QSlider *powerMinSlider; -}; \ No newline at end of file + QCheckBox *timeScaleCheckBox; + QLabel *cursorFrequencyLabel; + QLabel *cursorTimeLabel; + QCheckBox *deltaDragCheckBox; + QLabel *deltaFrequencyLabel; + QLabel *deltaTimeLabel; +};