changeset 115:90ade4fa63be

* Fix serious failure to reload "imported" (i.e. all non-derived non-main) models from .sv file * Give a short playback duration to notes with formal duration of 0 or 1 * Show crosshairs on spectrogram even when there is another layer on top (if it isn't opaque) * Always paste to the same time in the layer as the cut/copy was from, rather than to the playback pointer -- less flexible, but more predictable and less annoying. We probably need a way to get the old behaviour if pasting from somewhere else in the future (e.g. from a text file), but we can't do that yet anyway * Use a compound operation for dragging and resizing selections, so as to ensure a single undo operation works * Use a note model as the target for feature extraction plugins that output variable samplerate data with more than one value per feature * Avoid possible crashes in cut/paste if a layer proves to have no model
author Chris Cannam
date Thu, 11 May 2006 11:35:46 +0000
parents 8cd01027502f
children a08718723b20
files base/CommandHistory.cpp base/CommandHistory.h transform/FeatureExtractionPluginTransform.cpp
diffstat 3 files changed, 76 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/base/CommandHistory.cpp	Wed May 10 16:34:03 2006 +0000
+++ b/base/CommandHistory.cpp	Thu May 11 11:35:46 2006 +0000
@@ -115,12 +115,25 @@
 }
 
 void
+CommandHistory::addCommand(Command *command)
+{
+    if (!command) return;
+
+    if (m_currentCompound) {
+	addToCompound(command, m_executeCompound);
+	return;
+    }
+
+    addCommand(command, true);
+}
+
+void
 CommandHistory::addCommand(Command *command, bool execute, bool bundle)
 {
     if (!command) return;
 
     if (m_currentCompound) {
-	addToCompound(command);
+	addToCompound(command, execute);
 	return;
     }
 
@@ -198,11 +211,11 @@
 }
 
 void
-CommandHistory::addToCompound(Command *command)
+CommandHistory::addToCompound(Command *command, bool execute)
 {
 //    std::cerr << "CommandHistory::addToCompound: " << command->getName().toLocal8Bit().data() << std::endl;
 
-    if (m_executeCompound) command->execute();
+    if (execute) command->execute();
     m_currentCompound->addCommand(command);
 }
 
--- a/base/CommandHistory.h	Wed May 10 16:34:03 2006 +0000
+++ b/base/CommandHistory.h	Thu May 11 11:35:46 2006 +0000
@@ -65,6 +65,16 @@
 
     /**
      * Add a command to the command history.
+     * 
+     * The command will normally be executed before being added; but
+     * if a compound operation is in use (see startCompoundOperation
+     * below), the execute status of the compound operation will
+     * determine whether the command is executed or not.
+     */
+    void addCommand(Command *command);
+    
+    /**
+     * Add a command to the command history.
      *
      * If execute is true, the command will be executed before being
      * added.  Otherwise it will be assumed to have been already
@@ -72,8 +82,10 @@
      * its work has actually been done somehow!
      *
      * If a compound operation is in use (see startCompoundOperation
-     * below), the execute status of the compound operation will
-     * override any value of execute passed to this method.
+     * below), the execute value passed to this method will override
+     * the execute status of the compound operation.  In this way it's
+     * possible to have a compound operation mixing both to-execute
+     * and pre-executed commands.
      *
      * If bundle is true, the command will be a candidate for bundling
      * with any adjacent bundeable commands that have the same name,
@@ -83,7 +95,7 @@
      * not known in advance.  The bundle parameter will be ignored if
      * a compound operation is already in use.
      */
-    void addCommand(Command *command, bool execute = true, bool bundle = false);
+    void addCommand(Command *command, bool execute, bool bundle = false);
     
     /// Return the maximum number of items in the undo history.
     int getUndoLimit() const { return m_undoLimit; }
@@ -192,7 +204,7 @@
 
     MacroCommand *m_currentCompound;
     bool m_executeCompound;
-    void addToCompound(Command *command);
+    void addToCompound(Command *command, bool execute);
 
     MacroCommand *m_currentBundle;
     QString m_currentBundleName;
--- a/transform/FeatureExtractionPluginTransform.cpp	Wed May 10 16:34:03 2006 +0000
+++ b/transform/FeatureExtractionPluginTransform.cpp	Thu May 11 11:35:46 2006 +0000
@@ -26,6 +26,7 @@
 #include "model/SparseTimeValueModel.h"
 #include "model/DenseThreeDimensionalModel.h"
 #include "model/DenseTimeValueModel.h"
+#include "model/NoteModel.h"
 
 #include <fftw3.h>
 
@@ -165,13 +166,26 @@
 	m_output = new SparseOneDimensionalModel(modelRate, modelResolution,
 						 false);
 
-    } else if (binCount == 1 ||
+    } else if (binCount == 1) {
 
-	       // We don't have a sparse 3D model
-	       m_descriptor->sampleType ==
+        SparseTimeValueModel *model = new SparseTimeValueModel
+            (modelRate, modelResolution, minValue, maxValue, false);
+        model->setScaleUnits(outputs[m_outputFeatureNo].unit.c_str());
+
+        m_output = model;
+
+    } else if (m_descriptor->sampleType ==
 	       Vamp::Plugin::OutputDescriptor::VariableSampleRate) {
+
+        // We don't have a sparse 3D model, so interpret this as a
+        // note model.  There's nothing to define which values to use
+        // as which parameters of the note -- for the moment let's
+        // treat the first as pitch, second as duration in frames,
+        // third (if present) as velocity. (Our note model doesn't
+        // yet store velocity.)
+        //!!! todo: ask the user!
 	
-        SparseTimeValueModel *model = new SparseTimeValueModel
+        NoteModel *model = new NoteModel
             (modelRate, modelResolution, minValue, maxValue, false);
         model->setScaleUnits(outputs[m_outputFeatureNo].unit.c_str());
 
@@ -415,9 +429,7 @@
 	if (!model) return;
 	model->addPoint(SparseOneDimensionalModel::Point(frame, feature.label.c_str()));
 	
-    } else if (binCount == 1 ||
-	       m_descriptor->sampleType == 
-	       Vamp::Plugin::OutputDescriptor::VariableSampleRate) {
+    } else if (binCount == 1) {
 
 	float value = 0.0;
 	if (feature.values.size() > 0) value = feature.values[0];
@@ -425,6 +437,23 @@
 	SparseTimeValueModel *model = getOutput<SparseTimeValueModel>();
 	if (!model) return;
 	model->addPoint(SparseTimeValueModel::Point(frame, value, feature.label.c_str()));
+
+    } else if (m_descriptor->sampleType == 
+	       Vamp::Plugin::OutputDescriptor::VariableSampleRate) {
+
+        float pitch = 0.0;
+        if (feature.values.size() > 0) pitch = feature.values[0];
+
+        float duration = 1;
+        if (feature.values.size() > 1) duration = feature.values[1];
+        
+        float velocity = 100;
+        if (feature.values.size() > 2) velocity = feature.values[2];
+
+        NoteModel *model = getOutput<NoteModel>();
+        if (!model) return;
+
+        model->addPoint(NoteModel::Point(frame, pitch, duration, feature.label.c_str()));
 	
     } else {
 	
@@ -451,11 +480,16 @@
 	if (!model) return;
 	model->setCompletion(completion);
 
-    } else if (binCount == 1 ||
-	       m_descriptor->sampleType ==
+    } else if (binCount == 1) {
+
+	SparseTimeValueModel *model = getOutput<SparseTimeValueModel>();
+	if (!model) return;
+	model->setCompletion(completion);
+
+    } else if (m_descriptor->sampleType ==
 	       Vamp::Plugin::OutputDescriptor::VariableSampleRate) {
 
-	SparseTimeValueModel *model = getOutput<SparseTimeValueModel>();
+	NoteModel *model = getOutput<NoteModel>();
 	if (!model) return;
 	model->setCompletion(completion);