changeset 301:5636eeacc467

* Merge from sv-match-alignment branch (excluding alignment-specific document). - add aggregate wave model (not yet complete enough to be added as a true model in a layer, but there's potential) - add play solo mode - add alignment model -- unused in plain SV - fix two plugin leaks - add m3u playlist support (opens all files at once, potentially hazardous) - fix retrieval of pre-encoded URLs - add ability to resample audio files on import, so as to match rates with other files previously loaded; add preference for same - add preliminary support in transform code for range and rate of transform input - reorganise preferences dialog, move dark-background option to preferences, add option for temporary directory location
author Chris Cannam
date Fri, 28 Sep 2007 13:56:38 +0000
parents 0824a754a8eb
children e9549ea3f825
files layer/WaveformLayer.cpp view/Pane.cpp view/View.cpp view/View.h view/ViewManager.cpp view/ViewManager.h
diffstat 6 files changed, 121 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/layer/WaveformLayer.cpp	Thu Sep 06 15:17:35 2007 +0000
+++ b/layer/WaveformLayer.cpp	Fri Sep 28 13:56:38 2007 +0000
@@ -82,6 +82,9 @@
     connect(m_model, SIGNAL(completionChanged()),
 	    this, SIGNAL(modelCompletionChanged()));
 
+    connect(model, SIGNAL(alignmentCompletionChanged()),
+            this, SIGNAL(modelCompletionChanged()));
+
     emit modelReplaced();
 
     if (channelsChanged) emit layerParametersChanged();
--- a/view/Pane.cpp	Thu Sep 06 15:17:35 2007 +0000
+++ b/view/Pane.cpp	Fri Sep 28 13:56:38 2007 +0000
@@ -806,20 +806,23 @@
     if (r.y() + r.height() < height() - fontHeight - 6) return;
 
     size_t modelRate = waveformModel->getSampleRate();
+    size_t nativeRate = waveformModel->getNativeRate();
     size_t playbackRate = m_manager->getPlaybackSampleRate();
     size_t outputRate = m_manager->getOutputSampleRate();
         
     QString srNote = "";
 
-    // Show (R) for waveform models that will be resampled on
-    // playback, and (X) for waveform models that will be played
-    // at the wrong rate because their rate differs from the
+    // Show (R) for waveform models that have been resampled or will
+    // be resampled on playback, and (X) for waveform models that will
+    // be played at the wrong rate because their rate differs from the
     // current playback rate (which is not necessarily that of the
     // main model).
 
     if (playbackRate != 0) {
         if (modelRate == playbackRate) {
-            if (modelRate != outputRate) srNote = " " + tr("(R)");
+            if (modelRate != outputRate || modelRate != nativeRate) {
+                srNote = " " + tr("(R)");
+            }
         } else {
             srNote = " " + tr("(X)");
         }
@@ -829,7 +832,7 @@
         .arg(RealTime::frame2RealTime(waveformModel->getEndFrame(),
                                       sampleRate)
              .toText(false).c_str())
-        .arg(modelRate)
+        .arg(nativeRate)
         .arg(srNote);
 
     if (r.x() < m_scaleWidth + 5 + paint.fontMetrics().width(desc)) {
--- a/view/View.cpp	Thu Sep 06 15:17:35 2007 +0000
+++ b/view/View.cpp	Fri Sep 28 13:56:38 2007 +0000
@@ -20,9 +20,10 @@
 #include "base/Profiler.h"
 #include "base/Pitch.h"
 
-#include "layer/TimeRulerLayer.h" //!!! damn, shouldn't be including that here
+#include "layer/TimeRulerLayer.h"
 #include "layer/SingleColourLayer.h"
-#include "data/model/PowerOfSqrtTwoZoomConstraint.h" //!!! likewise
+#include "data/model/PowerOfSqrtTwoZoomConstraint.h"
+#include "data/model/RangeSummarisableTimeValueModel.h"
 
 #include <QPainter>
 #include <QPaintEvent>
@@ -801,6 +802,8 @@
 void
 View::modelCompletionChanged()
 {
+    std::cerr << "View(" << this << ")::modelCompletionChanged()" << std::endl;
+
     QObject *obj = sender();
     checkProgress(obj);
 }
@@ -877,6 +880,8 @@
 	if (sender() != m_manager) return;
     }
 
+    f = getAlignedPlaybackFrame();
+
     if (m_playPointerFrame == f) return;
     bool visible = (getXForFrame(m_playPointerFrame) != getXForFrame(f));
     size_t oldPlayPointerFrame = m_playPointerFrame;
@@ -1052,6 +1057,51 @@
     return 0;
 }
 
+int
+View::getAlignedPlaybackFrame() const
+{
+    if (!m_manager) return 0;
+    if (!m_manager->getPlaybackModel()) return m_manager->getPlaybackFrame();
+
+    RangeSummarisableTimeValueModel *waveformModel = 0;
+    for (LayerList::const_iterator i = m_layers.begin(); i != m_layers.end(); ++i) {
+
+        if (!*i) continue;
+        if (dynamic_cast<TimeRulerLayer *>(*i)) continue;
+
+        Model *model = (*i)->getModel();
+        if (!model) continue;
+
+        waveformModel = dynamic_cast<RangeSummarisableTimeValueModel *>(model);
+        if (!waveformModel) {
+            waveformModel = dynamic_cast<RangeSummarisableTimeValueModel *>
+                (model->getSourceModel());
+        }
+
+        if (waveformModel) break;
+    }
+
+    int pf = m_manager->getPlaybackFrame();
+
+    if (!waveformModel) return pf;
+
+    RangeSummarisableTimeValueModel *pm =
+        dynamic_cast<RangeSummarisableTimeValueModel *>
+        (m_manager->getPlaybackModel());
+
+//    std::cerr << "View[" << this << "]::getAlignedPlaybackFrame: pf = " << pf;
+
+    if (pm) {
+        pf = pm->alignFromReference(pf);
+//        std::cerr << " -> " << pf;
+    }
+
+    int af = waveformModel->alignToReference(pf);
+
+//    std::cerr << ", aligned = " << af << std::endl;
+    return af;
+}
+
 bool
 View::areLayersScrollable() const
 {
@@ -1232,6 +1282,21 @@
 	if (i->first == object) {
 
 	    int completion = i->first->getCompletion(this);
+            QString text = i->first->getPropertyContainerName();
+
+            if (completion >= 100) {
+
+                //!!!
+                Model *model = i->first->getModel();
+                RangeSummarisableTimeValueModel *wfm = 
+                    dynamic_cast<RangeSummarisableTimeValueModel *>(model);
+                if (wfm) {
+                    completion = wfm->getAlignmentCompletion();
+                    if (completion < 100) {
+                        text = tr("Alignment");
+                    }
+                }
+            }
 
 	    if (completion >= 100) {
 
@@ -1239,7 +1304,7 @@
 
 	    } else {
 
-		i->second->setText(i->first->getPropertyContainerName());
+		i->second->setText(text);
 
 		i->second->setValue(completion);
 		i->second->move(0, ph - i->second->height());
--- a/view/View.h	Thu Sep 06 15:17:35 2007 +0000
+++ b/view/View.h	Fri Sep 28 13:56:38 2007 +0000
@@ -252,6 +252,9 @@
     size_t getModelsStartFrame() const;
     size_t getModelsEndFrame() const;
 
+    //!!!
+    int getAlignedPlaybackFrame() const;
+
 signals:
     void propertyContainerAdded(PropertyContainer *pc);
     void propertyContainerRemoved(PropertyContainer *pc);
--- a/view/ViewManager.cpp	Thu Sep 06 15:17:35 2007 +0000
+++ b/view/ViewManager.cpp	Fri Sep 28 13:56:38 2007 +0000
@@ -31,6 +31,7 @@
     m_globalCentreFrame(0),
     m_globalZoom(1024),
     m_playbackFrame(0),
+    m_playbackModel(0),
     m_mainModelSampleRate(0),
     m_lastLeft(0), 
     m_lastRight(0),
@@ -38,6 +39,7 @@
     m_toolMode(NavigateMode),
     m_playLoopMode(false),
     m_playSelectionMode(false),
+    m_playSoloMode(false),
     m_overlayMode(StandardOverlays),
     m_zoomWheelsEnabled(true),
     m_lightPalette(QApplication::palette()),
@@ -156,6 +158,18 @@
     }
 }
 
+Model *
+ViewManager::getPlaybackModel() const
+{
+    return m_playbackModel;
+}
+
+void
+ViewManager::setPlaybackModel(Model *model)
+{
+    m_playbackModel = model;
+}
+
 bool
 ViewManager::haveInProgressSelection() const
 {
@@ -332,6 +346,18 @@
     }
 }
 
+void
+ViewManager::setPlaySoloMode(bool mode)
+{
+    if (m_playSoloMode != mode) {
+
+        m_playSoloMode = mode;
+
+        emit playSoloModeChanged();
+        emit playSoloModeChanged(mode);
+    }
+}
+
 size_t 
 ViewManager::getPlaybackSampleRate() const
 {
--- a/view/ViewManager.h	Thu Sep 06 15:17:35 2007 +0000
+++ b/view/ViewManager.h	Fri Sep 28 13:56:38 2007 +0000
@@ -65,6 +65,10 @@
     unsigned long getPlaybackFrame() const;
     void setPlaybackFrame(unsigned long frame);
 
+    // Only meaningful in solo mode, and used for optional alignment feature
+    Model *getPlaybackModel() const;
+    void setPlaybackModel(Model *);
+
     bool haveInProgressSelection() const;
     const Selection &getInProgressSelection(bool &exclusive) const;
     void setInProgressSelection(const Selection &selection, bool exclusive);
@@ -105,6 +109,9 @@
     bool getPlaySelectionMode() const { return m_playSelectionMode; }
     void setPlaySelectionMode(bool on);
 
+    bool getPlaySoloMode() const { return m_playSoloMode; }
+    void setPlaySoloMode(bool on);
+
     /**
      * The sample rate that is used for playback.  This is usually the
      * rate of the main model, but not always.  Models whose rates
@@ -199,6 +206,10 @@
     void playSelectionModeChanged();
     void playSelectionModeChanged(bool);
 
+    /** Emitted when the play solo mode has been changed. */
+    void playSoloModeChanged();
+    void playSoloModeChanged(bool);
+
     /** Emitted when the overlay mode has been changed. */
     void overlayModeChanged();
 
@@ -220,6 +231,7 @@
     unsigned long m_globalCentreFrame;
     unsigned long m_globalZoom;
     mutable unsigned long m_playbackFrame;
+    Model *m_playbackModel; //!!!
     size_t m_mainModelSampleRate;
 
     float m_lastLeft;
@@ -235,6 +247,7 @@
 
     bool m_playLoopMode;
     bool m_playSelectionMode;
+    bool m_playSoloMode;
 
     void setSelections(const MultiSelection &ms);
     void signalSelectionChange();