From eb5a31f7fd0282b5ad36f6132349c21fb3ec0bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Sat, 27 Feb 2016 23:43:51 +0100 Subject: [PATCH] Added cursors --- mainwindow.cpp | 4 ++++ spectrogram.cpp | 50 +++++++++++++++++++++++++++++++++++++++++ spectrogram.h | 13 +++++++++++ spectrogramcontrols.cpp | 12 ++++++++++ spectrogramcontrols.h | 5 +++++ 5 files changed, 84 insertions(+) diff --git a/mainwindow.cpp b/mainwindow.cpp index 20cee94..08c1140 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -39,6 +39,10 @@ MainWindow::MainWindow() connect(dock->powerMaxSlider, SIGNAL(valueChanged(int)), &spectrogram, SLOT(setPowerMax(int))); connect(dock->powerMinSlider, SIGNAL(valueChanged(int)), &spectrogram, SLOT(setPowerMin(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(&spectrogram, SIGNAL(deltaFrequencyChanged(QString)), dock->deltaFrequencyLabel, SLOT(setText(QString))); + connect(&spectrogram, SIGNAL(deltaTimeChanged(QString)), dock->deltaTimeLabel, SLOT(setText(QString))); } bool MainWindow::eventFilter(QObject * /*obj*/, QEvent *event) diff --git a/spectrogram.cpp b/spectrogram.cpp index b121548..b92ea43 100644 --- a/spectrogram.cpp +++ b/spectrogram.cpp @@ -41,6 +41,8 @@ Spectrogram::Spectrogram() float p = (float)i / 256; colormap[i] = QColor::fromHsvF(p * 0.83f, 1.0, 1.0 - p).rgba(); } + + setMouseTracking(true); } Spectrogram::~Spectrogram() @@ -73,6 +75,38 @@ template const T& clamp (const T& value, const T& min, const T& max) { return std::min(max, std::max(min, value)); } +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) { + 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) { + cursorEndX = cursorStartX = event->x(); + cursorEndY = cursorStartY = event->y(); + update(); +} + void Spectrogram::paintEvent(QPaintEvent *event) { QRect rect = event->rect(); @@ -96,6 +130,7 @@ void Spectrogram::paintEvent(QPaintEvent *event) } paintTimeAxis(&painter, rect); + paintCursors(&painter, rect); } } @@ -165,6 +200,21 @@ 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) { if (timeScaleIsEnabled){ diff --git a/spectrogram.h b/spectrogram.h index 7c07ca4..1514347 100644 --- a/spectrogram.h +++ b/spectrogram.h @@ -40,6 +40,12 @@ public: int getHeight(); int getStride(); +signals: + void cursorFrequencyChanged(QString); + void cursorTimeChanged(QString); + void deltaFrequencyChanged(QString); + void deltaTimeChanged(QString); + public slots: void openFile(QString fileName); void setSampleRate(int rate); @@ -51,6 +57,9 @@ public slots: protected: void paintEvent(QPaintEvent *event); + void mouseReleaseEvent(QMouseEvent * event); + void mouseMoveEvent(QMouseEvent * event); + void mousePressEvent(QMouseEvent * event); private: @@ -71,15 +80,19 @@ private: float powerMax; float powerMin; bool timeScaleIsEnabled; + 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); off_t lineToSample(off_t line); 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 d2a98d2..625b0fd 100644 --- a/spectrogramcontrols.cpp +++ b/spectrogramcontrols.cpp @@ -60,6 +60,18 @@ SpectrogramControls::SpectrogramControls(const QString & title, QWidget * parent 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); + + 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); diff --git a/spectrogramcontrols.h b/spectrogramcontrols.h index 40a3e19..6a9a165 100644 --- a/spectrogramcontrols.h +++ b/spectrogramcontrols.h @@ -25,6 +25,7 @@ #include #include #include +#include class SpectrogramControls : public QDockWidget { Q_OBJECT @@ -51,4 +52,8 @@ public: QSlider *powerMaxSlider; QSlider *powerMinSlider; QCheckBox *timeScaleCheckBox; + QLabel *cursorFrequencyLabel; + QLabel *cursorTimeLabel; + QLabel *deltaFrequencyLabel; + QLabel *deltaTimeLabel; };