From ab517450abb21405c78cd9aea241e760f7223b41 Mon Sep 17 00:00:00 2001 From: "Simon A. Eugster" Date: Mon, 27 Dec 2010 18:50:33 +0000 Subject: [PATCH] Audio Spectrum: Option to show maximum values added (decreases with the Moving Average). Easier to detect clipping. svn path=/trunk/kdenlive/; revision=5208 --- src/abstractscopewidget.cpp | 21 ++++++----- src/abstractscopewidget.h | 4 ++ src/audioscopes/audiospectrum.cpp | 61 +++++++++++++++++++++++-------- src/audioscopes/audiospectrum.h | 4 ++ 4 files changed, 66 insertions(+), 24 deletions(-) diff --git a/src/abstractscopewidget.cpp b/src/abstractscopewidget.cpp index 9bec497d..a3b328cd 100644 --- a/src/abstractscopewidget.cpp +++ b/src/abstractscopewidget.cpp @@ -32,15 +32,18 @@ const int REALTIME_FPS = 30; const QColor light(250, 238, 226, 255); const QColor dark(40, 40, 39, 255); const QColor dark2(25, 25, 23, 255); - -const QPen AbstractScopeWidget::penThick(QBrush(QColor(250, 250, 250)), 2, Qt::SolidLine); -const QPen AbstractScopeWidget::penThin(QBrush(QColor(250, 250, 250)), 1, Qt::SolidLine); -const QPen AbstractScopeWidget::penLight(QBrush(QColor(200, 200, 250, 150)), 1, Qt::SolidLine); -const QPen AbstractScopeWidget::penLightDots(QBrush(QColor(200, 200, 250, 150)), 1, Qt::DotLine); -const QPen AbstractScopeWidget::penLighter(QBrush(QColor(225, 225, 250, 225)), 1, Qt::SolidLine); -const QPen AbstractScopeWidget::penDark(QBrush(QColor(0, 0, 20, 250)), 1, Qt::SolidLine); -const QPen AbstractScopeWidget::penDarkDots(QBrush(QColor(0, 0, 20, 250)), 1, Qt::DotLine); -const QPen AbstractScopeWidget::penBackground(QBrush(dark2), 1, Qt::SolidLine); +const QColor AbstractScopeWidget::colHighlightLight(18, 130, 255, 255); +const QColor AbstractScopeWidget::colHighlightDark(255, 64, 19, 255); +const QColor AbstractScopeWidget::colDarkWhite(250, 250, 250); + +const QPen AbstractScopeWidget::penThick(QBrush(AbstractScopeWidget::colDarkWhite.rgb()), 2, Qt::SolidLine); +const QPen AbstractScopeWidget::penThin(QBrush(AbstractScopeWidget::colDarkWhite.rgb()), 1, Qt::SolidLine); +const QPen AbstractScopeWidget::penLight(QBrush(QColor(200, 200, 250, 150)), 1, Qt::SolidLine); +const QPen AbstractScopeWidget::penLightDots(QBrush(QColor(200, 200, 250, 150)), 1, Qt::DotLine); +const QPen AbstractScopeWidget::penLighter(QBrush(QColor(225, 225, 250, 225)), 1, Qt::SolidLine); +const QPen AbstractScopeWidget::penDark(QBrush(QColor(0, 0, 20, 250)), 1, Qt::SolidLine); +const QPen AbstractScopeWidget::penDarkDots(QBrush(QColor(0, 0, 20, 250)), 1, Qt::DotLine); +const QPen AbstractScopeWidget::penBackground(QBrush(dark2), 1, Qt::SolidLine); const QString AbstractScopeWidget::directions[] = {"North", "Northeast", "East", "Southeast"}; diff --git a/src/abstractscopewidget.h b/src/abstractscopewidget.h index d1c72654..a2515051 100644 --- a/src/abstractscopewidget.h +++ b/src/abstractscopewidget.h @@ -82,6 +82,10 @@ public: virtual QString widgetName() const = 0; ///// Variables ///// + static const QColor colHighlightLight; + static const QColor colHighlightDark; + static const QColor colDarkWhite; + static const QPen penThick; static const QPen penThin; static const QPen penLight; diff --git a/src/audioscopes/audiospectrum.cpp b/src/audioscopes/audiospectrum.cpp index 52ba211d..2f4e1db8 100644 --- a/src/audioscopes/audiospectrum.cpp +++ b/src/audioscopes/audiospectrum.cpp @@ -32,15 +32,17 @@ #define MIN_DB_VALUE -120 #define MAX_FREQ_VALUE 96000 #define MIN_FREQ_VALUE 1000 +#define ALPHA_MOVING_AVG 0.125 AudioSpectrum::AudioSpectrum(QWidget *parent) : - AbstractAudioScopeWidget(true, parent), - m_fftTools(), - m_lastFFT(), - m_lastFFTLock(1) + AbstractAudioScopeWidget(true, parent), + m_fftTools(), + m_lastFFT(), + m_lastFFTLock(1), + m_peaks() #ifdef DEBUG_AUDIOSPEC - ,m_timeTotal(0) - ,m_showTotal(0) + ,m_timeTotal(0) + ,m_showTotal(0) #endif { ui = new Ui::AudioSpectrum_UI; @@ -50,11 +52,14 @@ AudioSpectrum::AudioSpectrum(QWidget *parent) : m_aResetHz = new QAction(i18n("Reset maximum frequency to sampling rate"), this); m_aTrackMouse = new QAction(i18n("Track mouse"), this); m_aTrackMouse->setCheckable(true); + m_aShowMax = new QAction(i18n("Show maximum"), this); + m_aShowMax->setCheckable(true); m_menu->addSeparator(); m_menu->addAction(m_aResetHz); m_menu->addAction(m_aTrackMouse); + m_menu->addAction(m_aShowMax); m_menu->removeAction(m_aRealtime); @@ -100,6 +105,7 @@ void AudioSpectrum::readConfig() ui->windowSize->setCurrentIndex(scopeConfig.readEntry("windowSize", 0)); ui->windowFunction->setCurrentIndex(scopeConfig.readEntry("windowFunction", 0)); m_aTrackMouse->setChecked(scopeConfig.readEntry("trackMouse", true)); + m_aShowMax->setChecked(scopeConfig.readEntry("showMax", true)); m_dBmax = scopeConfig.readEntry("dBmax", 0); m_dBmin = scopeConfig.readEntry("dBmin", -70); m_freqMax = scopeConfig.readEntry("freqMax", 0); @@ -119,6 +125,7 @@ void AudioSpectrum::writeConfig() scopeConfig.writeEntry("windowSize", ui->windowSize->currentIndex()); scopeConfig.writeEntry("windowFunction", ui->windowFunction->currentIndex()); scopeConfig.writeEntry("trackMouse", m_aTrackMouse->isChecked()); + scopeConfig.writeEntry("showMax", m_aShowMax->isChecked()); scopeConfig.writeEntry("dBmax", m_dBmax); scopeConfig.writeEntry("dBmin", m_dBmin); if (m_customFreq) { @@ -182,7 +189,9 @@ QImage AudioSpectrum::renderAudioScope(uint, const QVector audioFrame, m_lastFFTLock.release(); +#ifdef DEBUG_AUDIOSPEC QTime drawTime = QTime::currentTime(); +#endif // Draw the spectrum QImage spectrum(m_scopeRect.size(), QImage::Format_ARGB32); @@ -214,6 +223,37 @@ QImage AudioSpectrum::renderAudioScope(uint, const QVector audioFrame, #endif } + // Calculate the peak values. Use the new value if it is bigger, otherwise adapt to lower + // values using the Moving Average formula + if (m_aShowMax->isChecked()) { + davinci.setPen(QPen(QBrush(AbstractScopeWidget::colHighlightLight), 2)); + if (m_peaks.size() != fftWindow/2) { + m_peaks = QVector(m_lastFFT); + } else { + for (int i = 0; i < fftWindow/2; i++) { + if (m_lastFFT[i] > m_peaks[i]) { + m_peaks[i] = m_lastFFT[i]; + } else { + m_peaks[i] = ALPHA_MOVING_AVG * m_lastFFT[i] + (1-ALPHA_MOVING_AVG) * m_peaks[i]; + } + } + } + int prev = 0; + m_peakMap = FFTTools::interpolatePeakPreserving(m_peaks, m_innerScopeRect.width(), 0, right, -180); + for (uint i = 0; i < w; i++) { + yMax = (m_peakMap[i] - m_dBmin) / (m_dBmax-m_dBmin) * (h-1); + if (yMax < 0) { + yMax = 0; + } else if (yMax >= (int)h) { + yMax = h-1; + } + + davinci.drawLine(leftDist + i-1, topDist + h-prev-1, leftDist + i, topDist + h-yMax-1); + spectrum.setPixel(leftDist + i, topDist + h-yMax-1, AbstractScopeWidget::colHighlightLight.rgba()); + prev = yMax; + } + } + #ifdef DEBUG_AUDIOSPEC m_showTotal++; m_timeTotal += drawTime.elapsed(); @@ -461,12 +501,3 @@ void AudioSpectrum::handleMouseDrag(const QPoint movement, const RescaleDirectio forceUpdateScope(); } } - - -#ifdef DEBUG_AUDIOSPEC -#undef DEBUG_AUDIOSPEC -#endif - -#undef MIN_DB_VALUE -#undef MAX_FREQ_VALUE -#undef MIN_FREQ_VALUE diff --git a/src/audioscopes/audiospectrum.h b/src/audioscopes/audiospectrum.h index 2a92cc4c..78d6cbc5 100644 --- a/src/audioscopes/audiospectrum.h +++ b/src/audioscopes/audiospectrum.h @@ -60,11 +60,15 @@ private: QAction *m_aResetHz; QAction *m_aTrackMouse; + QAction *m_aShowMax; FFTTools m_fftTools; QVector m_lastFFT; QSemaphore m_lastFFTLock; + QVector m_peaks; + QVector m_peakMap; + /** Contains the plot only; m_scopeRect contains text and widgets as well */ QRect m_innerScopeRect; -- 2.39.2