From 0e808597b76a888b3c292ad287abe154146c83c0 Mon Sep 17 00:00:00 2001 From: droelfdroelf Date: Sun, 20 Dec 2015 21:54:22 +0100 Subject: [PATCH 1/4] added time scale toggle checkbox --- mainwindow.cpp | 1 + spectrogram.cpp | 35 +++++++++++++++++++++++------------ spectrogram.h | 2 ++ spectrogramcontrols.cpp | 6 +++++- spectrogramcontrols.h | 4 +++- 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index c66b29d..20cee94 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -38,6 +38,7 @@ MainWindow::MainWindow() connect(dock->zoomLevelSlider, SIGNAL(valueChanged(int)), this, SLOT(setZoomLevel(int))); 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))); } bool MainWindow::eventFilter(QObject * /*obj*/, QEvent *event) diff --git a/spectrogram.cpp b/spectrogram.cpp index c70f201..b121548 100644 --- a/spectrogram.cpp +++ b/spectrogram.cpp @@ -35,6 +35,7 @@ Spectrogram::Spectrogram() zoomLevel = 0; powerMax = 0.0f; powerMin = -50.0f; + timeScaleIsEnabled = true; for (int i = 0; i < 256; i++) { float p = (float)i / 256; @@ -166,20 +167,22 @@ void Spectrogram::getLine(float *dest, off_t sample) 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) @@ -222,6 +225,14 @@ void Spectrogram::setZoomLevel(int zoom) resize(fftSize, getHeight()); } +void Spectrogram::setTimeScaleEnable(int state) +{ + timeScaleIsEnabled = (state == Qt::Checked); + pixmapCache.clear(); + update(); +} + + int Spectrogram::getHeight() { if (!inputSource) diff --git a/spectrogram.h b/spectrogram.h index 91d2713..7c07ca4 100644 --- a/spectrogram.h +++ b/spectrogram.h @@ -47,6 +47,7 @@ public slots: void setPowerMax(int power); void setPowerMin(int power); void setZoomLevel(int zoom); + void setTimeScaleEnable(int state); protected: void paintEvent(QPaintEvent *event); @@ -69,6 +70,7 @@ private: int zoomLevel; float powerMax; float powerMin; + bool timeScaleIsEnabled; QPixmap* getPixmapTile(off_t tile); float* getFFTTile(off_t tile); diff --git a/spectrogramcontrols.cpp b/spectrogramcontrols.cpp index 877ffc8..d2a98d2 100644 --- a/spectrogramcontrols.cpp +++ b/spectrogramcontrols.cpp @@ -56,6 +56,10 @@ 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); + widget->setLayout(layout); setWidget(widget); @@ -74,4 +78,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 1e03f4c..40a3e19 100644 --- a/spectrogramcontrols.h +++ b/spectrogramcontrols.h @@ -24,6 +24,7 @@ #include #include #include +#include class SpectrogramControls : public QDockWidget { Q_OBJECT @@ -49,4 +50,5 @@ public: QSlider *zoomLevelSlider; QSlider *powerMaxSlider; QSlider *powerMinSlider; -}; \ No newline at end of file + QCheckBox *timeScaleCheckBox; +}; 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 2/4] 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; }; From 649f7f4049ce4d52b712ee8aa9a284905fcd6fb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Sun, 28 Feb 2016 14:43:33 +0100 Subject: [PATCH 3/4] added dragless cursor delta measurement --- mainwindow.cpp | 1 + spectrogram.cpp | 20 ++++++++++++++++---- spectrogram.h | 2 ++ spectrogramcontrols.cpp | 4 ++++ spectrogramcontrols.h | 1 + 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 08c1140..3d185d0 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -41,6 +41,7 @@ MainWindow::MainWindow() 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))); } diff --git a/spectrogram.cpp b/spectrogram.cpp index b92ea43..195522d 100644 --- a/spectrogram.cpp +++ b/spectrogram.cpp @@ -36,6 +36,7 @@ Spectrogram::Spectrogram() powerMax = 0.0f; powerMin = -50.0f; timeScaleIsEnabled = true; + deltaDragIsEnabled = true; for (int i = 0; i < 256; i++) { float p = (float)i / 256; @@ -81,8 +82,10 @@ void Spectrogram::xyToFreqTime(int x, int y, float *freq, float *time) { } void Spectrogram::mouseReleaseEvent(QMouseEvent *event) { - cursorStartX = -1; - update(); + if (deltaDragIsEnabled) { + cursorStartX = -1; + update(); + } } void Spectrogram::mouseMoveEvent(QMouseEvent *event) { @@ -102,8 +105,12 @@ void Spectrogram::mouseMoveEvent(QMouseEvent *event) { } void Spectrogram::mousePressEvent(QMouseEvent *event) { - cursorEndX = cursorStartX = event->x(); - cursorEndY = cursorStartY = event->y(); + if (cursorStartX == -1) { + cursorEndX = cursorStartX = event->x(); + cursorEndY = cursorStartY = event->y(); + } else { + cursorStartX = -1; + } update(); } @@ -282,6 +289,11 @@ void Spectrogram::setTimeScaleEnable(int state) update(); } +void Spectrogram::setDeltaDragEnable(int state) +{ + deltaDragIsEnabled = (state == Qt::Checked); +} + int Spectrogram::getHeight() { diff --git a/spectrogram.h b/spectrogram.h index 1514347..d96b708 100644 --- a/spectrogram.h +++ b/spectrogram.h @@ -54,6 +54,7 @@ public slots: void setPowerMin(int power); void setZoomLevel(int zoom); void setTimeScaleEnable(int state); + void setDeltaDragEnable(int state); protected: void paintEvent(QPaintEvent *event); @@ -80,6 +81,7 @@ private: float powerMax; float powerMin; bool timeScaleIsEnabled; + bool deltaDragIsEnabled; int cursorStartX = -1, cursorStartY; int cursorEndX, cursorEndY; diff --git a/spectrogramcontrols.cpp b/spectrogramcontrols.cpp index 625b0fd..9f737b1 100644 --- a/spectrogramcontrols.cpp +++ b/spectrogramcontrols.cpp @@ -66,6 +66,10 @@ SpectrogramControls::SpectrogramControls(const QString & title, QWidget * parent 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); diff --git a/spectrogramcontrols.h b/spectrogramcontrols.h index 6a9a165..3f835aa 100644 --- a/spectrogramcontrols.h +++ b/spectrogramcontrols.h @@ -54,6 +54,7 @@ public: QCheckBox *timeScaleCheckBox; QLabel *cursorFrequencyLabel; QLabel *cursorTimeLabel; + QCheckBox *deltaDragCheckBox; QLabel *deltaFrequencyLabel; QLabel *deltaTimeLabel; }; From fd73720eab7b523677dbd5df988cf944a1e559e6 Mon Sep 17 00:00:00 2001 From: Mike Walters Date: Mon, 29 Feb 2016 22:39:18 +0000 Subject: [PATCH 4/4] Style --- fft.h | 7 +- inputsource.cpp | 6 +- inputsource.h | 4 +- main.cpp | 24 +-- mainwindow.h | 12 +- spectrogram.cpp | 384 +++++++++++++++++++++------------------- spectrogram.h | 132 +++++++------- spectrogramcontrols.cpp | 94 +++++----- spectrogramcontrols.h | 43 ++--- 9 files changed, 363 insertions(+), 343 deletions(-) diff --git a/fft.h b/fft.h index d30c456..adec9a7 100644 --- a/fft.h +++ b/fft.h @@ -21,12 +21,15 @@ #include -class FFT { +class FFT +{ public: FFT(int size); ~FFT(); void process(void *dest, void *source); - int getSize() { return fftSize; } + int getSize() { + return fftSize; + } private: int fftSize; diff --git a/inputsource.cpp b/inputsource.cpp index ca03fd3..197ed98 100644 --- a/inputsource.cpp +++ b/inputsource.cpp @@ -27,7 +27,8 @@ #include -InputSource::InputSource(const char *filename) { +InputSource::InputSource(const char *filename) +{ m_file = fopen(filename, "rb"); if (m_file == nullptr) throw std::runtime_error("Error opening file"); @@ -43,7 +44,8 @@ InputSource::InputSource(const char *filename) { throw std::runtime_error("Error mmapping file"); } -InputSource::~InputSource() { +InputSource::~InputSource() +{ munmap(m_data, m_file_size); fclose(m_file); } diff --git a/inputsource.h b/inputsource.h index ad310f2..ae8b0e0 100644 --- a/inputsource.h +++ b/inputsource.h @@ -36,5 +36,7 @@ public: ~InputSource(); bool getSamples(fftwf_complex *dest, off_t start, int length); - off_t getSampleCount() { return sampleCount; }; + off_t getSampleCount() { + return sampleCount; + }; }; diff --git a/main.cpp b/main.cpp index c922599..01ee997 100644 --- a/main.cpp +++ b/main.cpp @@ -35,27 +35,27 @@ int main(int argc, char *argv[]) // Add options QCommandLineOption rateOption(QStringList() << "r" << "rate", - QCoreApplication::translate("main", "Set sample rate."), - QCoreApplication::translate("main", "Hz")); + QCoreApplication::translate("main", "Set sample rate."), + QCoreApplication::translate("main", "Hz")); parser.addOption(rateOption); // Process the actual command line parser.process(a); - if (parser.isSet(rateOption)){ - bool ok; - // Use toDouble just for scientific notation support - int rate = parser.value(rateOption).toDouble(&ok); - if(!ok){ - fputs("ERROR: could not parse rate\n", stderr); - return 1; - } - mainWin.changeSampleRate(rate); + if (parser.isSet(rateOption)) { + bool ok; + // Use toDouble just for scientific notation support + int rate = parser.value(rateOption).toDouble(&ok); + if(!ok) { + fputs("ERROR: could not parse rate\n", stderr); + return 1; + } + mainWin.changeSampleRate(rate); } const QStringList args = parser.positionalArguments(); if (args.size()>=1) - mainWin.openFile(args.at(0)); + mainWin.openFile(args.at(0)); mainWin.show(); return a.exec(); diff --git a/mainwindow.h b/mainwindow.h index bdc53a4..3ab4e0c 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -34,18 +34,18 @@ public: public slots: void openFile(QString fileName); - void setSampleRate(QString rate); - void setFFTSize(int size); - void setZoomLevel(int zoom); + void setSampleRate(QString rate); + void setFFTSize(int size); + void setZoomLevel(int zoom); protected: - bool eventFilter(QObject *obj, QEvent *event); + bool eventFilter(QObject *obj, QEvent *event); private: QScrollArea scrollArea; Spectrogram spectrogram; SpectrogramControls *dock; - off_t getCenterSample(); - int getScrollPos(off_t sample); + off_t getCenterSample(); + int getScrollPos(off_t sample); }; diff --git a/spectrogram.cpp b/spectrogram.cpp index 195522d..ff18517 100644 --- a/spectrogram.cpp +++ b/spectrogram.cpp @@ -30,301 +30,311 @@ Spectrogram::Spectrogram() { - sampleRate = 8000000; - setFFTSize(1024); - zoomLevel = 0; - powerMax = 0.0f; - powerMin = -50.0f; - timeScaleIsEnabled = true; - deltaDragIsEnabled = true; + sampleRate = 8000000; + setFFTSize(1024); + 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(); - } + 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); + setMouseTracking(true); } Spectrogram::~Spectrogram() { - delete fft; - delete inputSource; + delete fft; + delete inputSource; } -QSize Spectrogram::sizeHint() const { - return QSize(1024, 2048); +QSize Spectrogram::sizeHint() const +{ + return QSize(1024, 2048); } void Spectrogram::openFile(QString fileName) { - if (fileName != nullptr) { - try { - InputSource *newFile = new InputSource(fileName.toUtf8().constData()); - delete inputSource; - pixmapCache.clear(); - fftCache.clear(); - inputSource = newFile; - resize(fftSize, getHeight()); - } catch (std::runtime_error e) { - // TODO: display error - } - } + if (fileName != nullptr) { + try { + InputSource *newFile = new InputSource(fileName.toUtf8().constData()); + delete inputSource; + pixmapCache.clear(); + fftCache.clear(); + inputSource = newFile; + resize(fftSize, getHeight()); + } catch (std::runtime_error e) { + // TODO: display error + } + } } -template const T& clamp (const T& value, const T& min, const T& max) { +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::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::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::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::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(); - QPainter painter(this); - painter.fillRect(rect, Qt::black); + QRect rect = event->rect(); + QPainter painter(this); + painter.fillRect(rect, Qt::black); - if (inputSource != nullptr) { - int height = rect.height(); - off_t y = rect.y(); + if (inputSource != nullptr) { + int height = rect.height(); + off_t y = rect.y(); - QImage image(fftSize, height, QImage::Format_RGB32); + QImage image(fftSize, height, QImage::Format_RGB32); - while (height > 0) { - int tileOffset = y % linesPerTile(); // To handle drawing a partial first tile - int drawHeight = std::min(linesPerTile() - tileOffset, height); // Draw rest of first tile, full tile, or partial final tile - off_t tileId = lineToSample(y - tileOffset); - QPixmap *tile = getPixmapTile(tileId); - painter.drawPixmap(QRect(0, y, fftSize, drawHeight), *tile, QRect(0, tileOffset, fftSize, drawHeight)); - y += drawHeight; - height -= drawHeight; - } + while (height > 0) { + int tileOffset = y % linesPerTile(); // To handle drawing a partial first tile + int drawHeight = std::min(linesPerTile() - tileOffset, height); // Draw rest of first tile, full tile, or partial final tile + off_t tileId = lineToSample(y - tileOffset); + QPixmap *tile = getPixmapTile(tileId); + painter.drawPixmap(QRect(0, y, fftSize, drawHeight), *tile, QRect(0, tileOffset, fftSize, drawHeight)); + y += drawHeight; + height -= drawHeight; + } - paintTimeAxis(&painter, rect); - paintCursors(&painter, rect); - } + paintTimeAxis(&painter, rect); + paintCursors(&painter, rect); + } } QPixmap* Spectrogram::getPixmapTile(off_t tile) { - QPixmap *obj = pixmapCache.object(TileCacheKey(fftSize, zoomLevel, tile)); - if (obj != 0) - return obj; + QPixmap *obj = pixmapCache.object(TileCacheKey(fftSize, zoomLevel, tile)); + if (obj != 0) + return obj; - float *fftTile = getFFTTile(tile); - obj = new QPixmap(fftSize, linesPerTile()); - QImage image(fftSize, linesPerTile(), QImage::Format_RGB32); - for (int y = 0; y < linesPerTile(); y++) { - float *line = &fftTile[y * fftSize]; - for (int x = 0; x < fftSize; x++) { - float powerRange = std::abs(int(powerMin - powerMax)); - float normPower = (line[x] - powerMax) * -1.0f / powerRange; - normPower = clamp(normPower, 0.0f, 1.0f); + float *fftTile = getFFTTile(tile); + obj = new QPixmap(fftSize, linesPerTile()); + QImage image(fftSize, linesPerTile(), QImage::Format_RGB32); + for (int y = 0; y < linesPerTile(); y++) { + float *line = &fftTile[y * fftSize]; + for (int x = 0; x < fftSize; x++) { + float powerRange = std::abs(int(powerMin - powerMax)); + float normPower = (line[x] - powerMax) * -1.0f / powerRange; + normPower = clamp(normPower, 0.0f, 1.0f); - image.setPixel(x, y, colormap[(uint8_t)(normPower * (256 - 1))]); - } - } - obj->convertFromImage(image); - pixmapCache.insert(TileCacheKey(fftSize, zoomLevel, tile), obj); - return obj; + image.setPixel(x, y, colormap[(uint8_t)(normPower * (256 - 1))]); + } + } + obj->convertFromImage(image); + pixmapCache.insert(TileCacheKey(fftSize, zoomLevel, tile), obj); + return obj; } float* Spectrogram::getFFTTile(off_t tile) { - float *obj = fftCache.object(TileCacheKey(fftSize, zoomLevel, tile)); - if (obj != 0) - return obj; + float *obj = fftCache.object(TileCacheKey(fftSize, zoomLevel, tile)); + if (obj != 0) + return obj; - float *dest = new float[tileSize]; - float *ptr = dest; - off_t sample = tile; - while ((ptr - dest) < tileSize) { - getLine(ptr, sample); - sample += getStride(); - ptr += fftSize; - } - fftCache.insert(TileCacheKey(fftSize, zoomLevel, tile), dest); - return dest; + float *dest = new float[tileSize]; + float *ptr = dest; + off_t sample = tile; + while ((ptr - dest) < tileSize) { + getLine(ptr, sample); + sample += getStride(); + ptr += fftSize; + } + fftCache.insert(TileCacheKey(fftSize, zoomLevel, tile), dest); + return dest; } void Spectrogram::getLine(float *dest, off_t sample) { - if (inputSource && fft) { - fftwf_complex buffer[fftSize]; - inputSource->getSamples(buffer, sample, fftSize); + if (inputSource && fft) { + fftwf_complex buffer[fftSize]; + inputSource->getSamples(buffer, sample, fftSize); - for (int i = 0; i < fftSize; i++) { - buffer[i][0] *= window[i]; - buffer[i][1] *= window[i]; - } + for (int i = 0; i < fftSize; i++) { + buffer[i][0] *= window[i]; + buffer[i][1] *= window[i]; + } - fft->process(buffer, buffer); - for (int i = 0; i < fftSize; i++) { - int k = (i + fftSize / 2) % fftSize; - float re = buffer[k][0]; - float im = buffer[k][1]; - float mag = sqrt(re * re + im * im) / fftSize; - float magdb = 10 * log2(mag) / log2(10); - *dest = magdb; - dest++; - } - } + fft->process(buffer, buffer); + for (int i = 0; i < fftSize; i++) { + int k = (i + fftSize / 2) % fftSize; + float re = buffer[k][0]; + float im = buffer[k][1]; + float mag = sqrt(re * re + im * im) / fftSize; + float magdb = 10 * log2(mag) / log2(10); + *dest = magdb; + dest++; + } + } } 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(); + 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){ - // 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->restore(); - } + 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(); + } } void Spectrogram::setSampleRate(int rate) { - sampleRate = rate; - update(); + sampleRate = rate; + update(); } void Spectrogram::setFFTSize(int size) { - fftSize = size; - delete fft; - fft = new FFT(fftSize); + fftSize = size; + delete fft; + fft = new FFT(fftSize); - window.reset(new float[fftSize]); - for (int i = 0; i < fftSize; i++) { - window[i] = 0.5f * (1.0f - cos(Tau * i / (fftSize - 1))); - } + window.reset(new float[fftSize]); + for (int i = 0; i < fftSize; i++) { + window[i] = 0.5f * (1.0f - cos(Tau * i / (fftSize - 1))); + } - resize(fftSize, getHeight()); + resize(fftSize, getHeight()); } void Spectrogram::setPowerMax(int power) { - powerMax = power; - pixmapCache.clear(); - update(); + powerMax = power; + pixmapCache.clear(); + update(); } void Spectrogram::setPowerMin(int power) { - powerMin = power; - pixmapCache.clear(); - update(); + powerMin = power; + pixmapCache.clear(); + update(); } void Spectrogram::setZoomLevel(int zoom) { - zoomLevel = clamp(zoom, 0, (int)log2(fftSize)); - resize(fftSize, getHeight()); + zoomLevel = clamp(zoom, 0, (int)log2(fftSize)); + resize(fftSize, getHeight()); } void Spectrogram::setTimeScaleEnable(int state) { - timeScaleIsEnabled = (state == Qt::Checked); - pixmapCache.clear(); - update(); + timeScaleIsEnabled = (state == Qt::Checked); + pixmapCache.clear(); + update(); } void Spectrogram::setDeltaDragEnable(int state) { - deltaDragIsEnabled = (state == Qt::Checked); + deltaDragIsEnabled = (state == Qt::Checked); } int Spectrogram::getHeight() { - if (!inputSource) - return 0; + if (!inputSource) + return 0; - return inputSource->getSampleCount() / getStride(); + return inputSource->getSampleCount() / getStride(); } int Spectrogram::getStride() { - return fftSize / pow(2, zoomLevel); + return fftSize / pow(2, zoomLevel); } -off_t Spectrogram::lineToSample(off_t line) { - return line * getStride(); +off_t Spectrogram::lineToSample(off_t line) +{ + return line * getStride(); } -int Spectrogram::sampleToLine(off_t sample) { - return sample / getStride(); +int Spectrogram::sampleToLine(off_t sample) +{ + return sample / getStride(); } QString Spectrogram::sampleToTime(off_t sample) { - return QString::number((float)sample / sampleRate).append("s"); + return QString::number((float)sample / sampleRate).append("s"); } -int Spectrogram::linesPerTile() { - return tileSize / fftSize; +int Spectrogram::linesPerTile() +{ + return tileSize / fftSize; } -uint qHash(const TileCacheKey &key, uint seed) { - return key.fftSize ^ key.zoomLevel ^ key.sample ^ seed; +uint qHash(const TileCacheKey &key, uint seed) +{ + return key.fftSize ^ key.zoomLevel ^ key.sample ^ seed; } diff --git a/spectrogram.h b/spectrogram.h index d96b708..e73f9f1 100644 --- a/spectrogram.h +++ b/spectrogram.h @@ -30,89 +30,91 @@ static const double Tau = M_PI * 2.0; class TileCacheKey; -class Spectrogram : public QWidget { - Q_OBJECT +class Spectrogram : public QWidget +{ + Q_OBJECT public: - Spectrogram(); - ~Spectrogram(); - QSize sizeHint() const; - int getHeight(); - int getStride(); + Spectrogram(); + ~Spectrogram(); + QSize sizeHint() const; + int getHeight(); + int getStride(); signals: - void cursorFrequencyChanged(QString); - void cursorTimeChanged(QString); - void deltaFrequencyChanged(QString); - void deltaTimeChanged(QString); + void cursorFrequencyChanged(QString); + void cursorTimeChanged(QString); + void deltaFrequencyChanged(QString); + void deltaTimeChanged(QString); public slots: - void openFile(QString fileName); - void setSampleRate(int rate); - void setFFTSize(int size); - void setPowerMax(int power); - void setPowerMin(int power); - void setZoomLevel(int zoom); - void setTimeScaleEnable(int state); - void setDeltaDragEnable(int state); + void openFile(QString fileName); + void setSampleRate(int rate); + void setFFTSize(int size); + 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); + void paintEvent(QPaintEvent *event); + void mouseReleaseEvent(QMouseEvent * event); + void mouseMoveEvent(QMouseEvent * event); + void mousePressEvent(QMouseEvent * event); private: - const int linesPerGraduation = 50; - const int tileSize = 65536; // This must be a multiple of the maximum FFT size + const int linesPerGraduation = 50; + const int tileSize = 65536; // This must be a multiple of the maximum FFT size - InputSource *inputSource = nullptr; - FFT *fft = nullptr; - std::unique_ptr window; - fftwf_complex *lineBuffer = nullptr; - QCache pixmapCache; - QCache fftCache; - uint colormap[256]; + InputSource *inputSource = nullptr; + FFT *fft = nullptr; + std::unique_ptr window; + fftwf_complex *lineBuffer = nullptr; + QCache pixmapCache; + QCache fftCache; + uint colormap[256]; - int sampleRate; - int fftSize; - int zoomLevel; - float powerMax; - float powerMin; - bool timeScaleIsEnabled; - bool deltaDragIsEnabled; - int cursorStartX = -1, cursorStartY; - int cursorEndX, cursorEndY; + int sampleRate; + int fftSize; + 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); - 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); + 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 { +class TileCacheKey +{ public: - TileCacheKey(int fftSize, int zoomLevel, off_t sample) { - this->fftSize = fftSize; - this->zoomLevel = zoomLevel; - this->sample = sample; - } + TileCacheKey(int fftSize, int zoomLevel, off_t sample) { + this->fftSize = fftSize; + this->zoomLevel = zoomLevel; + this->sample = sample; + } - bool operator==(const TileCacheKey &k2) const { - return (this->fftSize == k2.fftSize) && - (this->zoomLevel == k2.zoomLevel) && - (this->sample == k2.sample); - } + bool operator==(const TileCacheKey &k2) const { + return (this->fftSize == k2.fftSize) && + (this->zoomLevel == k2.zoomLevel) && + (this->sample == k2.sample); + } - int fftSize; - int zoomLevel; - off_t sample; + int fftSize; + int zoomLevel; + off_t sample; }; diff --git a/spectrogramcontrols.cpp b/spectrogramcontrols.cpp index 9f737b1..438137f 100644 --- a/spectrogramcontrols.cpp +++ b/spectrogramcontrols.cpp @@ -24,74 +24,74 @@ #include SpectrogramControls::SpectrogramControls(const QString & title, QWidget * parent) - : QDockWidget::QDockWidget(title, parent) + : QDockWidget::QDockWidget(title, parent) { - widget = new QWidget(this); - layout = new QFormLayout(widget); + widget = new QWidget(this); + layout = new QFormLayout(widget); - fileOpenButton = new QPushButton("Open file...", widget); - layout->addRow(fileOpenButton); + fileOpenButton = new QPushButton("Open file...", widget); + layout->addRow(fileOpenButton); - sampleRate = new QLineEdit("8000000"); - sampleRate->setValidator(new QIntValidator(this)); - layout->addRow(new QLabel(tr("Sample rate:")), sampleRate); + sampleRate = new QLineEdit("8000000"); + sampleRate->setValidator(new QIntValidator(this)); + layout->addRow(new QLabel(tr("Sample rate:")), sampleRate); - fftSizeSlider = new QSlider(Qt::Horizontal, widget); - fftSizeSlider->setRange(7, 13); - fftSizeSlider->setValue(10); - layout->addRow(new QLabel(tr("FFT size:")), fftSizeSlider); + fftSizeSlider = new QSlider(Qt::Horizontal, widget); + fftSizeSlider->setRange(7, 13); + fftSizeSlider->setValue(10); + layout->addRow(new QLabel(tr("FFT size:")), fftSizeSlider); - zoomLevelSlider = new QSlider(Qt::Horizontal, widget); - zoomLevelSlider->setRange(0, 5); - zoomLevelSlider->setValue(0); - layout->addRow(new QLabel(tr("Zoom:")), zoomLevelSlider); + zoomLevelSlider = new QSlider(Qt::Horizontal, widget); + zoomLevelSlider->setRange(0, 5); + zoomLevelSlider->setValue(0); + layout->addRow(new QLabel(tr("Zoom:")), zoomLevelSlider); - powerMaxSlider = new QSlider(Qt::Horizontal, widget); - powerMaxSlider->setRange(-100, 20); - powerMaxSlider->setValue(0); - layout->addRow(new QLabel(tr("Power max:")), powerMaxSlider); + powerMaxSlider = new QSlider(Qt::Horizontal, widget); + powerMaxSlider->setRange(-100, 20); + powerMaxSlider->setValue(0); + layout->addRow(new QLabel(tr("Power max:")), powerMaxSlider); - powerMinSlider = new QSlider(Qt::Horizontal, widget); - powerMinSlider->setRange(-100, 20); - powerMinSlider->setValue(-50); - layout->addRow(new QLabel(tr("Power min:")), powerMinSlider); + powerMinSlider = new QSlider(Qt::Horizontal, widget); + powerMinSlider->setRange(-100, 20); + 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); + 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); + cursorFrequencyLabel = new QLabel(); + layout->addRow(new QLabel(tr("Cursor frequency:")), cursorFrequencyLabel); - cursorTimeLabel = new QLabel(); - layout->addRow(new QLabel(tr("Cursor time:")), cursorTimeLabel); + 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); + 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); + deltaFrequencyLabel = new QLabel(); + layout->addRow(new QLabel(tr("Delta frequency:")), deltaFrequencyLabel); - deltaTimeLabel = new QLabel(); - layout->addRow(new QLabel(tr("Delta time:")), deltaTimeLabel); + deltaTimeLabel = new QLabel(); + layout->addRow(new QLabel(tr("Delta time:")), deltaTimeLabel); - widget->setLayout(layout); - setWidget(widget); + widget->setLayout(layout); + setWidget(widget); - connect(fftSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(fftSizeSliderChanged(int))); - connect(fileOpenButton, SIGNAL(clicked()), this, SLOT(fileOpenButtonClicked())); + connect(fftSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(fftSizeSliderChanged(int))); + connect(fileOpenButton, SIGNAL(clicked()), this, SLOT(fileOpenButtonClicked())); } void SpectrogramControls::fftSizeSliderChanged(int size) { - emit fftSizeChanged((int)pow(2, size)); + emit fftSizeChanged((int)pow(2, size)); } void SpectrogramControls::fileOpenButtonClicked() { - QString fileName = QFileDialog::getOpenFileName( - this, tr("Open File"), "", tr("Sample file (*.cfile *.bin);;All files (*)") - ); - emit openFile(fileName); + QString fileName = QFileDialog::getOpenFileName( + this, tr("Open File"), "", tr("Sample file (*.cfile *.bin);;All files (*)") + ); + emit openFile(fileName); } diff --git a/spectrogramcontrols.h b/spectrogramcontrols.h index 3f835aa..943deb5 100644 --- a/spectrogramcontrols.h +++ b/spectrogramcontrols.h @@ -27,34 +27,35 @@ #include #include -class SpectrogramControls : public QDockWidget { - Q_OBJECT +class SpectrogramControls : public QDockWidget +{ + Q_OBJECT public: - SpectrogramControls(const QString & title, QWidget * parent); + SpectrogramControls(const QString & title, QWidget * parent); signals: - void fftSizeChanged(int size); - void openFile(QString fileName); + void fftSizeChanged(int size); + void openFile(QString fileName); private slots: - void fftSizeSliderChanged(int size); - void fileOpenButtonClicked(); + void fftSizeSliderChanged(int size); + void fileOpenButtonClicked(); private: - QWidget *widget; - QFormLayout *layout; + QWidget *widget; + QFormLayout *layout; public: - QPushButton *fileOpenButton; - QLineEdit *sampleRate; - QSlider *fftSizeSlider; - QSlider *zoomLevelSlider; - QSlider *powerMaxSlider; - QSlider *powerMinSlider; - QCheckBox *timeScaleCheckBox; - QLabel *cursorFrequencyLabel; - QLabel *cursorTimeLabel; - QCheckBox *deltaDragCheckBox; - QLabel *deltaFrequencyLabel; - QLabel *deltaTimeLabel; + QPushButton *fileOpenButton; + QLineEdit *sampleRate; + QSlider *fftSizeSlider; + QSlider *zoomLevelSlider; + QSlider *powerMaxSlider; + QSlider *powerMinSlider; + QCheckBox *timeScaleCheckBox; + QLabel *cursorFrequencyLabel; + QLabel *cursorTimeLabel; + QCheckBox *deltaDragCheckBox; + QLabel *deltaFrequencyLabel; + QLabel *deltaTimeLabel; };