changeset 192:431a95c9d14d

Calculate frequency constraint for region outlining (does not actually do the analysis correctly yet)
author Chris Cannam
date Wed, 05 Mar 2014 09:36:13 +0000
parents 800e65412473
children abfbe8c2883b
files .hgsubstate src/Analyser.cpp src/Analyser.h src/MainWindow.cpp src/MainWindow.h
diffstat 5 files changed, 85 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/.hgsubstate	Tue Mar 04 16:45:54 2014 +0000
+++ b/.hgsubstate	Wed Mar 05 09:36:13 2014 +0000
@@ -2,4 +2,4 @@
 27d4e7152c954bf3c4387319db088fb3cd02436b sv-dependency-builds
 350a410e05551b78f5df02966c17ed35e2937067 svapp
 d81c16e47e22b1c1a6600d3e9a8e0559fad8b539 svcore
-711ae36a53a2730780bc59cb75b2d1c0d39026d0 svgui
+f831ca41d4a556cbc75aa5a180cf1e6a8d5598b5 svgui
--- a/src/Analyser.cpp	Tue Mar 04 16:45:54 2014 +0000
+++ b/src/Analyser.cpp	Wed Mar 05 09:36:13 2014 +0000
@@ -74,11 +74,6 @@
     m_paneStack = paneStack;
     m_pane = pane;
 
-    disconnect(m_pane, SIGNAL(regionOutlined(QRect)),
-               m_pane, SLOT(zoomToRegion(QRect)));
-    connect(m_pane, SIGNAL(regionOutlined(QRect)),
-            this, SLOT(regionOutlined(QRect)));
-
     m_reAnalysingSelection = Selection();
     m_reAnalysisCandidates.clear();
     m_currentCandidate = -1;
@@ -255,14 +250,8 @@
     return "";
 }
 
-void
-Analyser::regionOutlined(QRect r)
-{
-    cerr << "regionOutlined(" << r.x() << "," << r.y() << "," << r.width() << "," << r.height() << ")" << endl;
-}
-
 QString
-Analyser::reAnalyseSelection(Selection sel)
+Analyser::reAnalyseSelection(Selection sel, FrequencyRange range)
 {
     if (sel == m_reAnalysingSelection) return "";
 
@@ -276,6 +265,11 @@
     QString base = "vamp:pyin:localcandidatepyin:";
     QString out = "pitchtrackcandidates";
 
+    if (range.isConstrained()) {
+        base = "vamp:pyin:yinfc:";
+        out = "f0";
+    }
+
     Transforms transforms;
 
     QString notFound = tr("Transform \"%1\" not found. Unable to perform interactive analysis.<br><br>Is the %2 Vamp plugin correctly installed?");
@@ -288,6 +282,11 @@
     t.setStepSize(256);
     t.setBlockSize(2048);
 
+    if (range.isConstrained()) {
+        t.setParameter("minfreq", range.min);
+        t.setParameter("maxfreq", range.max);
+    }
+
     RealTime start = RealTime::frame2RealTime
         (round(sel.getStartFrame()*1.0/256) * 256 - 2*256, m_fileModel->getSampleRate());
 
--- a/src/Analyser.h	Tue Mar 04 16:45:54 2014 +0000
+++ b/src/Analyser.h	Wed Mar 05 09:36:13 2014 +0000
@@ -84,12 +84,22 @@
 
     void getEnclosingSelectionScope(size_t f, size_t &f0, size_t &f1);
 
+    struct FrequencyRange {
+        FrequencyRange() : min(0), max(0) { }
+        FrequencyRange(float min_, float max_) : min(min_), max(max_) { }
+        bool isConstrained() const { return min != max; }
+        float min;
+        float max;
+    };
+
     /**
      * Analyse the selection and schedule asynchronous adds of
      * candidate layers for the region it contains. Returns "" on
-     * success or a user-readable error string on failure.
+     * success or a user-readable error string on failure. If the
+     * frequency range isConstrained(), analysis will be constrained
+     * to that range.
      */
-    QString reAnalyseSelection(Selection sel);
+    QString reAnalyseSelection(Selection sel, FrequencyRange range);
 
     /**
      * Return true if the analysed pitch candidates are currently
@@ -150,9 +160,6 @@
 signals:
     void layersChanged();
 
-protected slots:
-    void regionOutlined(QRect);
-
 protected:
     Document *m_document;
     WaveFileModel *m_fileModel;
--- a/src/MainWindow.cpp	Tue Mar 04 16:45:54 2014 +0000
+++ b/src/MainWindow.cpp	Wed Mar 05 09:36:13 2014 +0000
@@ -34,6 +34,7 @@
 #include "layer/WaveformLayer.h"
 #include "layer/TimeInstantLayer.h"
 #include "layer/TimeValueLayer.h"
+#include "layer/SpectrogramLayer.h"
 #include "widgets/Fader.h"
 #include "view/Overview.h"
 #include "widgets/AudioDial.h"
@@ -150,8 +151,8 @@
     m_viewManager->setShowCentreLine(false);
     m_viewManager->setOverlayMode(ViewManager::MinimalOverlays);
 
-    connect(m_viewManager, SIGNAL(selectionChanged()),
-	    this, SLOT(selectionChanged()));
+    connect(m_viewManager, SIGNAL(selectionChangedByUser()),
+	    this, SLOT(selectionChangedByUser()));
 
     QFrame *frame = new QFrame;
     setCentralWidget(frame);
@@ -1783,24 +1784,65 @@
 }
 
 void
-MainWindow::selectionChanged()
+MainWindow::selectionChangedByUser()
 {
     MultiSelection::SelectionList selections = m_viewManager->getSelections();
 
-    cerr << "MainWindow::selectionChanged" << endl;
-
-    m_analyser->showPitchCandidates(false);
+    cerr << "MainWindow::selectionChangedByUser" << endl;
+
+    m_analyser->showPitchCandidates(m_pendingConstraint.isConstrained());
 
     if (!selections.empty()) {
         Selection sel = *selections.begin();
-        cerr << "MainWindow::selectionChanged: have selection" << endl;
-        QString error = m_analyser->reAnalyseSelection(sel);
+        cerr << "MainWindow::selectionChangedByUser: have selection" << endl;
+        QString error = m_analyser->reAnalyseSelection
+            (sel, m_pendingConstraint);
         if (error != "") {
             QMessageBox::critical
                 (this, tr("Failed to analyse selection"),
                  tr("<b>Analysis failed</b><p>%2</p>").arg(error));
         }
     }
+
+    m_pendingConstraint = Analyser::FrequencyRange();
+}
+
+void
+MainWindow::regionOutlined(QRect r)
+{
+    cerr << "MainWindow::regionOutlined(" << r.x() << "," << r.y() << "," << r.width() << "," << r.height() << ")" << endl;
+
+    Pane *pane = qobject_cast<Pane *>(sender());
+    if (!pane) {
+        cerr << "MainWindow::regionOutlined: not sent by pane, ignoring" << endl;
+        return;
+    }
+
+    if (!m_analyser) {
+        cerr << "MainWindow::regionOutlined: no analyser, ignoring" << endl;
+        return;
+    }
+
+    SpectrogramLayer *spectrogram = qobject_cast<SpectrogramLayer *>
+        (m_analyser->getLayer(Analyser::Spectrogram));
+    if (!spectrogram) {
+        cerr << "MainWindow::regionOutlined: no spectrogram layer, ignoring" << endl;
+        return;
+    }
+
+    int f0 = pane->getFrameForX(r.x());
+    int f1 = pane->getFrameForX(r.x() + r.width());
+    
+    float v0 = spectrogram->getFrequencyForY(pane, r.y() + r.height());
+    float v1 = spectrogram->getFrequencyForY(pane, r.y());
+
+    cerr << "MainWindow::regionOutlined: frame " << f0 << " -> " << f1 
+         << ", frequency " << v0 << " -> " << v1 << endl;
+
+    m_pendingConstraint = Analyser::FrequencyRange(v0, v1);
+
+    Selection sel(f0, f1);
+    m_viewManager->setSelection(sel);
 }
 
 void
@@ -2355,6 +2397,12 @@
             }
 
             if (pane) {
+
+                disconnect(pane, SIGNAL(regionOutlined(QRect)),
+                           pane, SLOT(zoomToRegion(QRect)));
+                connect(pane, SIGNAL(regionOutlined(QRect)),
+                        this, SLOT(regionOutlined(QRect)));
+
                 QString error = m_analyser->newFileLoaded
                     (m_document, getMainModel(), m_paneStack, pane);
                 if (error != "") {
--- a/src/MainWindow.h	Tue Mar 04 16:45:54 2014 +0000
+++ b/src/MainWindow.h	Wed Mar 05 09:36:13 2014 +0000
@@ -17,8 +17,8 @@
 #define _MAIN_WINDOW_H_
 
 #include "framework/MainWindowBase.h"
+#include "Analyser.h"
 
-class Analyser;
 class VersionTester;
 
 class MainWindow : public MainWindowBase
@@ -156,7 +156,8 @@
     virtual void about();
     virtual void keyReference();
 
-    virtual void selectionChanged();
+    virtual void selectionChangedByUser();
+    virtual void regionOutlined(QRect);
 
 protected:
     Analyser      *m_analyser;
@@ -203,6 +204,8 @@
     KeyReference  *m_keyReference;
     VersionTester *m_versionTester;
 
+    Analyser::FrequencyRange m_pendingConstraint;
+
     QString exportToSVL(QString path, Layer *layer);
     FileOpenStatus importPitchLayer(FileSource source);