changeset 302:e9549ea3f825

* Change WaveFileModel API from getValues(start,end) to getData(start,count). It's much less error-prone to pass in frame counts instead of start/end locations. Should have done this ages ago. This closes #1794563. * Add option to apply a transform to only the selection region, instead of the whole audio. * (to make the above work properly) Add start frame offset to wave models
author Chris Cannam
date Mon, 01 Oct 2007 13:48:38 +0000
parents 5636eeacc467
children 46faec7aae12
files layer/WaveformLayer.cpp widgets/PluginParameterDialog.cpp widgets/PluginParameterDialog.h
diffstat 3 files changed, 116 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/layer/WaveformLayer.cpp	Fri Sep 28 13:56:38 2007 +0000
+++ b/layer/WaveformLayer.cpp	Mon Oct 01 13:48:38 2007 +0000
@@ -404,6 +404,7 @@
     }
   
     long startFrame = v->getStartFrame();
+    long endFrame = v->getEndFrame();
     int zoomLevel = v->getZoomLevel();
 
 #ifdef DEBUG_WAVEFORM_PAINT
@@ -479,7 +480,7 @@
 
     long frame0 = v->getFrameForX(x0);
     long frame1 = v->getFrameForX(x1 + 1);
-     
+
 #ifdef DEBUG_WAVEFORM_PAINT
     std::cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << ")" <<  std::endl;
 #endif
@@ -506,21 +507,39 @@
         m_effectiveGains.push_back(m_gain);
     }
 
+    // Although a long for purposes of comparison against the view
+    // start and end frames, these are known to be non-negative
+    long modelStart = long(m_model->getStartFrame());
+    long modelEnd = long(m_model->getEndFrame());
+
+#ifdef DEBUG_WAVEFORM_PAINT
+    std::cerr << "Model start = " << modelStart << ", end = " << modelEnd << std::endl;
+#endif
+
     for (size_t ch = minChannel; ch <= maxChannel; ++ch) {
 
 	int prevRangeBottom = -1, prevRangeTop = -1;
 	QColor prevRangeBottomColour = baseColour, prevRangeTopColour = baseColour;
+        size_t rangeStart, rangeEnd;
 
         m_effectiveGains[ch] = m_gain;
 
         if (m_autoNormalize) {
+
+            if (startFrame < modelStart) rangeStart = modelStart;
+            else rangeStart = startFrame;
+
+            if (endFrame < 0) rangeEnd = 0;
+            else if (endFrame > modelEnd) rangeEnd = modelEnd;
+            else rangeEnd = endFrame;
+
+            if (rangeEnd < rangeStart) rangeEnd = rangeStart;
+
             RangeSummarisableTimeValueModel::Range range =
-                m_model->getRange(ch, startFrame < 0 ? 0 : startFrame,
-                                  v->getEndFrame());
+                m_model->getSummary(ch, rangeStart, rangeEnd - rangeStart);
             if (mergingChannels || mixingChannels) {
                 RangeSummarisableTimeValueModel::Range otherRange =
-                    m_model->getRange(1, startFrame < 0 ? 0 : startFrame,
-                                      v->getEndFrame());
+                    m_model->getSummary(1, rangeStart, rangeEnd - rangeStart);
                 range.max = std::max(range.max, otherRange.max);
                 range.min = std::min(range.min, otherRange.min);
                 range.absmean = std::min(range.absmean, otherRange.absmean);
@@ -595,12 +614,23 @@
             }
         }
 
-	if (frame1 <= 0) continue;
+	if (frame1 < modelStart) continue;
 
 	size_t modelZoomLevel = zoomLevel;
 
-	m_model->getRanges
-	    (ch, frame0 < 0 ? 0 : frame0, frame1, *ranges, modelZoomLevel);
+        if (frame0 < modelStart) rangeStart = modelStart;
+        else rangeStart = frame0;
+
+        if (frame1 < 0) rangeEnd = 0;
+        else if (frame1 > modelEnd) rangeEnd = modelEnd;
+        else rangeEnd = frame1;
+        
+        if (rangeEnd < rangeStart) rangeEnd = rangeStart;
+
+	m_model->getSummaries
+	    (ch, rangeStart, rangeEnd - rangeStart, *ranges, modelZoomLevel);
+
+//        std::cerr << ranges->size() << " ranges" << std::endl;
         
 	if (mergingChannels || mixingChannels) {
             if (m_model->getChannelCount() > 1) {
@@ -608,8 +638,8 @@
                     otherChannelRanges =
                         new RangeSummarisableTimeValueModel::RangeBlock;
                 }
-                m_model->getRanges
-                    (1, frame0 < 0 ? 0 : frame0, frame1, *otherChannelRanges,
+                m_model->getSummaries
+                    (1, rangeStart, rangeEnd - rangeStart, *otherChannelRanges,
                      modelZoomLevel);
             } else {
                 if (otherChannelRanges != ranges) delete otherChannelRanges;
@@ -623,14 +653,14 @@
 	    size_t index = x - x0;
 	    size_t maxIndex = index;
 
-	    if (frame0 < 0) {
-		if (index < size_t(-frame0 / zoomLevel)) {
-		    continue;
-		} else {
-		    index -= -frame0 / zoomLevel;
-		    maxIndex = index;
-		}
-	    }
+            if (frame0 < modelStart) {
+                if (index < size_t((modelStart - frame0) / zoomLevel)) {
+                    continue;
+                } else {
+                    index -= ((modelStart - frame0) / zoomLevel);
+                    maxIndex = index;
+                }
+            }
             
 	    if (int(modelZoomLevel) != zoomLevel) {
 
@@ -891,7 +921,7 @@
 
 	size_t blockSize = v->getZoomLevel();
 	RangeSummarisableTimeValueModel::RangeBlock ranges;
-        m_model->getRanges(ch, f0, f1, ranges, blockSize);
+        m_model->getSummaries(ch, f0, f1 - f0, ranges, blockSize);
 
 	if (ranges.empty()) continue;
 	
--- a/widgets/PluginParameterDialog.cpp	Fri Sep 28 13:56:38 2007 +0000
+++ b/widgets/PluginParameterDialog.cpp	Mon Oct 01 13:48:38 2007 +0000
@@ -32,6 +32,7 @@
 #include <QPushButton>
 #include <QMessageBox>
 #include <QComboBox>
+#include <QCheckBox>
 #include <QSettings>
 #include <QDialogButtonBox>
 
@@ -43,7 +44,8 @@
     m_stepSize(0),
     m_blockSize(0),
     m_windowType(HanningWindow),
-    m_parameterBox(0)
+    m_parameterBox(0),
+    m_selectionOnly(false)
 {
     setWindowTitle(tr("Plugin Parameters"));
 
@@ -161,13 +163,19 @@
     subgrid->setColumnStretch(1, 2);
 
     m_inputModelBox = new QGroupBox;
-    m_inputModelBox->setTitle(tr("Input Source"));
+    m_inputModelBox->setTitle(tr("Input Material"));
     grid->addWidget(m_inputModelBox, 1, 0);
     
     m_inputModels = new QComboBox;
-    QHBoxLayout *inputLayout = new QHBoxLayout;
+    QVBoxLayout *inputLayout = new QVBoxLayout;
     m_inputModelBox->setLayout(inputLayout);
     inputLayout->addWidget(m_inputModels);
+    m_inputModels->hide();
+
+    m_selectionOnly = new QCheckBox(tr("Restrict to selection extents"));
+    inputLayout->addWidget(m_selectionOnly);
+    m_selectionOnly->hide();
+
     m_inputModelBox->hide();
 
     QGroupBox *paramBox = new QGroupBox;
@@ -437,6 +445,8 @@
     QString lastModel = settings.value("lastinputmodel").toString();
     settings.endGroup();
 
+    m_inputModels->show();
+
     m_inputModelList = models;
     m_inputModels->addItems(TextAbbrev::abbreviate(models, 80));
     m_inputModels->setCurrentIndex(0);
@@ -456,12 +466,41 @@
     m_inputModelBox->show();
 }
 
+void
+PluginParameterDialog::setShowSelectionOnlyOption(bool show)
+{
+    if (!show) {
+        m_selectionOnly->hide();
+        if (!m_inputModels->isVisible()) m_inputModelBox->hide();
+        return;
+    }
+
+    QSettings settings;
+    settings.beginGroup("PluginParameterDialog");
+    bool lastSelectionOnly = settings.value("lastselectiononly", false).toBool();
+    settings.endGroup();
+
+    m_selectionOnly->setChecked(lastSelectionOnly);
+
+    connect(m_selectionOnly, SIGNAL(stateChanged(int)),
+            this, SLOT(selectionOnlyChanged(int)));
+
+    m_selectionOnly->show();
+    m_inputModelBox->show();
+}
+
 QString
 PluginParameterDialog::getInputModel() const
 {
     return m_currentInputModel;
 }
 
+bool
+PluginParameterDialog::getSelectionOnly() const
+{
+    return m_selectionOnly;
+}
+
 void
 PluginParameterDialog::getProcessingParameters(size_t &blockSize) const
 {
@@ -551,16 +590,29 @@
 }
 
 void
+PluginParameterDialog::selectionOnlyChanged(int state)
+{
+    if (state == Qt::Checked) {
+        m_currentSelectionOnly = true;
+    } else {
+        m_currentSelectionOnly = false;
+    }
+}
+
+void
 PluginParameterDialog::dialogAccepted()
 {
-    if (!m_inputModels || !m_inputModels->isVisible()) {
-        accept();
-        return;
-    }
-  
     QSettings settings;
     settings.beginGroup("PluginParameterDialog");
-    settings.setValue("lastinputmodel", getInputModel());
+
+    if (m_inputModels->isVisible()) {
+        settings.setValue("lastinputmodel", getInputModel());
+    }
+
+    if (m_selectionOnly->isVisible()) {
+        settings.setValue("lastselectiononly", getSelectionOnly());
+    }
+
     settings.endGroup();
     
     accept();
--- a/widgets/PluginParameterDialog.h	Fri Sep 28 13:56:38 2007 +0000
+++ b/widgets/PluginParameterDialog.h	Mon Oct 01 13:48:38 2007 +0000
@@ -27,6 +27,7 @@
 class QLabel;
 class QGroupBox;
 class QComboBox;
+class QCheckBox;
 
 /**
  * A dialog for editing the parameters of a given plugin, using a
@@ -54,12 +55,14 @@
                                   bool showFrequencyDomainOptions);
 
     void setCandidateInputModels(const QStringList &names);
+    void setShowSelectionOnlyOption(bool show);
 
     Vamp::PluginBase *getPlugin() { return m_plugin; }
 
     int getChannel() const { return m_channel; }
 
     QString getInputModel() const;
+    bool getSelectionOnly() const;
 
     //!!! merge with PluginTransform::ExecutionContext
 
@@ -79,6 +82,7 @@
     void advancedToggled();
     void setAdvancedVisible(bool);
     void inputModelComboChanged(int);
+    void selectionOnlyChanged(int);
     void dialogAccepted();
 
 protected:
@@ -104,8 +108,10 @@
 
     QGroupBox *m_inputModelBox;
     QComboBox *m_inputModels;
+    QCheckBox *m_selectionOnly;
     QStringList m_inputModelList;
     QString m_currentInputModel;
+    bool m_currentSelectionOnly;
 
     QPushButton *m_advancedButton;
     QWidget *m_advanced;