# HG changeset patch # User Chris Cannam # Date 1147347346 0 # Node ID 90ade4fa63be6537812d0db436a4cd7b4e7f50f9 # Parent 8cd01027502f91657ca6cb934aef7dac5dc04ce9 * 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 diff -r 8cd01027502f -r 90ade4fa63be base/CommandHistory.cpp --- 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); } diff -r 8cd01027502f -r 90ade4fa63be base/CommandHistory.h --- 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; diff -r 8cd01027502f -r 90ade4fa63be transform/FeatureExtractionPluginTransform.cpp --- 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 @@ -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(); 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(); + 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(); + if (!model) return; + model->setCompletion(completion); + + } else if (m_descriptor->sampleType == Vamp::Plugin::OutputDescriptor::VariableSampleRate) { - SparseTimeValueModel *model = getOutput(); + NoteModel *model = getOutput(); if (!model) return; model->setCompletion(completion);