]> git.sesse.net Git - kdenlive/commitdiff
Audio Spectrum updated
authorSimon A. Eugster <simon.eu@gmail.com>
Sat, 4 Dec 2010 08:41:42 +0000 (08:41 +0000)
committerSimon A. Eugster <simon.eu@gmail.com>
Sat, 4 Dec 2010 08:41:42 +0000 (08:41 +0000)
* Minimum dB value can be adjusted by dragging vertically
* Maximum dB value: Additionally hold Shift while dragging

svn path=/trunk/kdenlive/; revision=5132

src/audioscopes/audiospectrum.cpp
src/audioscopes/audiospectrum.h
src/colorscopes/abstractgfxscopewidget.cpp

index e03497e94a6d82237bf6ad6e6e43020dc6c96b0e..044362a142d36cacf88fb639441c008f3902f7e9 100644 (file)
 
 #include <QMenu>
 #include <QPainter>
+#include <QMouseEvent>
 
-// Linear interpolation.
-//#include <iostream>
-//#include <fstream>
+#include <iostream>
+#include <fstream>
 
 bool fileWritten = false;
 
+const QString AudioSpectrum::directions[] =  {"North", "Northeast", "East", "Southeast"};
+
 AudioSpectrum::AudioSpectrum(QWidget *parent) :
-        AbstractAudioScopeWidget(true, parent)
+        AbstractAudioScopeWidget(false, parent),
+        m_rescaleMinDist(12),
+        m_rescaleVerticalThreshold(2.0f),
+        m_rescaleActive(false),
+        m_rescalePropertiesLocked(false),
+        m_rescaleScale(1)
 {
     ui = new Ui::AudioSpectrum_UI;
     ui->setupUi(this);
@@ -41,9 +48,17 @@ AudioSpectrum::AudioSpectrum(QWidget *parent) :
     m_agScale->addAction(m_aLin);
     m_agScale->addAction(m_aLog);
 
-    m_menu->addSeparator()->setText(i18n("Scale"));
-    m_menu->addAction(m_aLin);
-    m_menu->addAction(m_aLog);
+    m_aLockHz = new QAction(i18n("Lock maximum frequency"), this);
+    m_aLockHz->setCheckable(true);
+    m_aLockHz->setEnabled(false);
+
+
+//    m_menu->addSeparator()->setText(i18n("Scale"));
+//    m_menu->addAction(m_aLin);
+//    m_menu->addAction(m_aLog);
+    m_menu->addSeparator();
+    m_menu->addAction(m_aLockHz);
+
 
     ui->windowSize->addItem("256", QVariant(256));
     ui->windowSize->addItem("512", QVariant(512));
@@ -65,6 +80,7 @@ AudioSpectrum::~AudioSpectrum()
     delete m_agScale;
     delete m_aLin;
     delete m_aLog;
+    delete m_aLockHz;
 }
 
 void AudioSpectrum::readConfig()
@@ -79,6 +95,7 @@ void AudioSpectrum::readConfig()
     } else {
         m_aLog->setChecked(true);
     }
+    m_aLockHz->setChecked(scopeConfig.readEntry("lockHz", false));
     ui->windowSize->setCurrentIndex(scopeConfig.readEntry("windowSize", 0));
 
 }
@@ -94,6 +111,7 @@ void AudioSpectrum::writeConfig()
     }
     scopeConfig.writeEntry("scale", scale);
     scopeConfig.writeEntry("windowSize", ui->windowSize->currentIndex());
+    scopeConfig.writeEntry("lockHz", m_aLockHz->isChecked());
     scopeConfig.sync();
 }
 
@@ -185,7 +203,7 @@ QImage AudioSpectrum::renderAudioScope(uint, const QVector<int16_t> audioFrame,
             }
 
             // freqSpectrum values range from 0 to -inf as they are relative dB values.
-            qDebug() << val << "/" <<  (1 - (val - m_dBmax)/(m_dBmin-m_dBmax));
+//            qDebug() << val << "/" <<  (1 - (val - m_dBmax)/(m_dBmin-m_dBmax));
             for (uint y = 0; y < h*(1 - (val - m_dBmax)/(m_dBmin-m_dBmax)) && y < h; y++) {
                 spectrum.setPixel(i, h-y-1, qRgba(225, 182, 255, 255));
             }
@@ -220,7 +238,7 @@ QImage AudioSpectrum::renderAudioScope(uint, const QVector<int16_t> audioFrame,
         } else {
             qDebug() << "File already written.";
         }
-        */
+        //*/
 
         if (customCfg) {
             free(myCfg);
@@ -253,7 +271,7 @@ QImage AudioSpectrum::renderHUD(uint)
     for (int db = -dbDiff; db > m_dBmin; db -= dbDiff) {
         y = rect.height() * ((float)db)/(m_dBmin - m_dBmax);
         davinci.drawLine(0, y, rect.width()-1, y);
-        davinci.drawText(rect.width() + textDist, y + 8, i18n("%1 dB", db));
+        davinci.drawText(rect.width() + textDist, y + 8, i18n("%1 dB", m_dBmax + db));
     }
 
 
@@ -281,3 +299,132 @@ void AudioSpectrum::slotUpdateCfg()
     free(m_cfg);
     m_cfg = kiss_fftr_alloc(ui->windowSize->itemData(ui->windowSize->currentIndex()).toInt(), 0,0,0);
 }
+
+
+///// EVENTS /////
+
+void AudioSpectrum::mouseMoveEvent(QMouseEvent *event)
+{
+//    qDebug() << "Mouse moved; Modifier: " << event->modifiers() << ", xy: " << event->x() << "/" << event->y()
+//            << ", Buttons: " << event->buttons();
+
+    QPoint movement = event->pos()-m_rescaleStartPoint;
+
+    if (m_rescaleActive) {
+        if (m_rescalePropertiesLocked) {
+            // Direction is known, now adjust parameters
+
+            // Reset the starting point to make the next moveEvent relative to the current one
+            m_rescaleStartPoint = event->pos();
+
+
+            if (!m_rescaleFirstRescaleDone) {
+                // We have just learned the desired direction; Normalize the movement to one pixel
+                // to avoid a jump by m_rescaleMinDist
+
+                if (movement.x() != 0) {
+                    movement.setX(movement.x() / abs(movement.x()));
+                }
+                if (movement.y() != 0) {
+                    movement.setY(movement.y() / abs(movement.y()));
+                }
+
+                m_rescaleFirstRescaleDone = true;
+            }
+
+            if (m_rescaleClockDirection == AudioSpectrum::North) {
+                // Nort-South direction: Adjust the dB scale
+
+                if ((m_rescaleModifiers & Qt::ShiftModifier) == 0) {
+
+                    // By default adjust the min dB value
+                    m_dBmin += movement.y();
+
+                } else {
+
+                    // Adjust max dB value if Shift is pressed.
+                    m_dBmax += movement.y();
+
+                }
+
+                // Ensure the dB values lie in [-100, 0]
+                // 0 is the upper bound, everything below -70 dB is most likely noise
+                if (m_dBmax > 0) {
+                    m_dBmax = 0;
+                }
+                if (m_dBmin < -100) {
+                    m_dBmin = -100;
+                }
+                // Ensure there is at least 6 dB between the minimum and the maximum value;
+                // lower values hardly make sense
+                if (m_dBmax - m_dBmin < 6) {
+                    if ((m_rescaleModifiers & Qt::ShiftModifier) == 0) {
+                        // min was adjusted; Try to adjust the max value to maintain the
+                        // minimum dB difference of 6 dB
+                        m_dBmax = m_dBmin + 6;
+                        if (m_dBmax > 0) {
+                            m_dBmax = 0;
+                            m_dBmin = -6;
+                        }
+                    } else {
+                        // max was adjusted, adjust min
+                        m_dBmin = m_dBmax - 6;
+                        if (m_dBmin < -100) {
+                            m_dBmin = -100;
+                            m_dBmax = -100+6;
+                        }
+                    }
+                }
+
+                forceUpdateHUD();
+                forceUpdateScope();
+
+            }
+
+
+        } else {
+            // Detect the movement direction here.
+            // This algorithm relies on the aspect ratio of dy/dx (size and signum).
+            if (movement.manhattanLength() > m_rescaleMinDist) {
+                float diff = ((float) movement.y())/movement.x();
+
+                if (abs(diff) > m_rescaleVerticalThreshold || movement.x() == 0) {
+                    m_rescaleClockDirection = AudioSpectrum::North;
+                } else if (abs(diff) < 1/m_rescaleVerticalThreshold) {
+                    m_rescaleClockDirection = AudioSpectrum::East;
+                } else if (diff < 0) {
+                    m_rescaleClockDirection = AudioSpectrum::Northeast;
+                } else {
+                    m_rescaleClockDirection = AudioSpectrum::Southeast;
+                }
+//                qDebug() << "Diff is " << diff << "; chose " << directions[m_rescaleClockDirection] << " as direction";
+                m_rescalePropertiesLocked = true;
+            }
+        }
+    } else {
+        AbstractAudioScopeWidget::mouseMoveEvent(event);
+    }
+}
+
+void AudioSpectrum::mousePressEvent(QMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton) {
+        // Rescaling mode starts
+        m_rescaleActive = true;
+        m_rescalePropertiesLocked = false;
+        m_rescaleFirstRescaleDone = false;
+        m_rescaleStartPoint = event->pos();
+        m_rescaleModifiers = event->modifiers();
+
+    } else {
+        AbstractAudioScopeWidget::mousePressEvent(event);
+    }
+}
+
+void AudioSpectrum::mouseReleaseEvent(QMouseEvent *event)
+{
+    m_rescaleActive = false;
+    m_rescalePropertiesLocked = false;
+
+    AbstractAudioScopeWidget::mouseReleaseEvent(event);
+}
index 9a65a6499bda827d063f02c8d57f557fed62ca57..3e714895ee8cedb991b2ddee479dade1b9d0a543 100644 (file)
@@ -29,6 +29,11 @@ public:
     // Implemented virtual methods
     QString widgetName() const;
 
+    static const QString directions[]; // Mainly for debug output
+    enum RescaleDirection { North, Northeast, East, Southeast };
+    enum RescaleDimension { Min_dB, Max_dB, Max_Hz };
+
+
 protected:
     ///// Implemented methods /////
     QRect scopeRect();
@@ -41,10 +46,15 @@ protected:
     virtual void readConfig();
     void writeConfig();
 
+    void mouseMoveEvent(QMouseEvent *event);
+    void mousePressEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *event);
+
 private:
     Ui::AudioSpectrum_UI *ui;
     kiss_fftr_cfg m_cfg;
 
+    QAction *m_aLockHz;
     QAction *m_aLin;
     QAction *m_aLog;
     QActionGroup *m_agScale;
@@ -56,8 +66,25 @@ private:
     /** Upper bound (max: 0) */
     int m_dBmax;
 
+    /** Maximum frequency (depends on the sampling rate)
+        Stored for the HUD painter */
     uint m_freqMax;
 
+
+    ///// Movement detection /////
+    const int m_rescaleMinDist;
+    const float m_rescaleVerticalThreshold;
+
+    bool m_rescaleActive;
+    bool m_rescalePropertiesLocked;
+    bool m_rescaleFirstRescaleDone;
+    short m_rescaleScale;
+    Qt::KeyboardModifiers m_rescaleModifiers;
+    AudioSpectrum::RescaleDirection m_rescaleClockDirection;
+    QPoint m_rescaleStartPoint;
+
+
+
 private slots:
     void slotUpdateCfg();
 
index 509ea1dbfbf2f9a241a8322cc8fc134ff1ba57a1..232eb2618fea9ad2d023723b03ed17fb8a936352 100644 (file)
@@ -24,8 +24,8 @@ const int REALTIME_FPS = 30;
 
 AbstractGfxScopeWidget::AbstractGfxScopeWidget(Monitor *projMonitor, Monitor *clipMonitor, bool trackMouse, QWidget *parent) :
         AbstractScopeWidget(trackMouse, parent),
-        m_clipMonitor(clipMonitor),
-        m_projMonitor(projMonitor)
+        m_projMonitor(projMonitor),
+        m_clipMonitor(clipMonitor)
 
 {
     m_activeRender = (m_clipMonitor->isActive()) ? m_clipMonitor->render : m_projMonitor->render;