comparison transform/FeatureExtractionPluginTransform.cpp @ 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 c30728d5625c
comparison
equal deleted inserted replaced
114:8cd01027502f 115:90ade4fa63be
24 #include "base/Window.h" 24 #include "base/Window.h"
25 #include "model/SparseOneDimensionalModel.h" 25 #include "model/SparseOneDimensionalModel.h"
26 #include "model/SparseTimeValueModel.h" 26 #include "model/SparseTimeValueModel.h"
27 #include "model/DenseThreeDimensionalModel.h" 27 #include "model/DenseThreeDimensionalModel.h"
28 #include "model/DenseTimeValueModel.h" 28 #include "model/DenseTimeValueModel.h"
29 #include "model/NoteModel.h"
29 30
30 #include <fftw3.h> 31 #include <fftw3.h>
31 32
32 #include <iostream> 33 #include <iostream>
33 34
163 if (binCount == 0) { 164 if (binCount == 0) {
164 165
165 m_output = new SparseOneDimensionalModel(modelRate, modelResolution, 166 m_output = new SparseOneDimensionalModel(modelRate, modelResolution,
166 false); 167 false);
167 168
168 } else if (binCount == 1 || 169 } else if (binCount == 1) {
169 170
170 // We don't have a sparse 3D model 171 SparseTimeValueModel *model = new SparseTimeValueModel
171 m_descriptor->sampleType == 172 (modelRate, modelResolution, minValue, maxValue, false);
173 model->setScaleUnits(outputs[m_outputFeatureNo].unit.c_str());
174
175 m_output = model;
176
177 } else if (m_descriptor->sampleType ==
172 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { 178 Vamp::Plugin::OutputDescriptor::VariableSampleRate) {
173 179
174 SparseTimeValueModel *model = new SparseTimeValueModel 180 // We don't have a sparse 3D model, so interpret this as a
181 // note model. There's nothing to define which values to use
182 // as which parameters of the note -- for the moment let's
183 // treat the first as pitch, second as duration in frames,
184 // third (if present) as velocity. (Our note model doesn't
185 // yet store velocity.)
186 //!!! todo: ask the user!
187
188 NoteModel *model = new NoteModel
175 (modelRate, modelResolution, minValue, maxValue, false); 189 (modelRate, modelResolution, minValue, maxValue, false);
176 model->setScaleUnits(outputs[m_outputFeatureNo].unit.c_str()); 190 model->setScaleUnits(outputs[m_outputFeatureNo].unit.c_str());
177 191
178 m_output = model; 192 m_output = model;
179 193
413 427
414 SparseOneDimensionalModel *model = getOutput<SparseOneDimensionalModel>(); 428 SparseOneDimensionalModel *model = getOutput<SparseOneDimensionalModel>();
415 if (!model) return; 429 if (!model) return;
416 model->addPoint(SparseOneDimensionalModel::Point(frame, feature.label.c_str())); 430 model->addPoint(SparseOneDimensionalModel::Point(frame, feature.label.c_str()));
417 431
418 } else if (binCount == 1 || 432 } else if (binCount == 1) {
419 m_descriptor->sampleType ==
420 Vamp::Plugin::OutputDescriptor::VariableSampleRate) {
421 433
422 float value = 0.0; 434 float value = 0.0;
423 if (feature.values.size() > 0) value = feature.values[0]; 435 if (feature.values.size() > 0) value = feature.values[0];
424 436
425 SparseTimeValueModel *model = getOutput<SparseTimeValueModel>(); 437 SparseTimeValueModel *model = getOutput<SparseTimeValueModel>();
426 if (!model) return; 438 if (!model) return;
427 model->addPoint(SparseTimeValueModel::Point(frame, value, feature.label.c_str())); 439 model->addPoint(SparseTimeValueModel::Point(frame, value, feature.label.c_str()));
440
441 } else if (m_descriptor->sampleType ==
442 Vamp::Plugin::OutputDescriptor::VariableSampleRate) {
443
444 float pitch = 0.0;
445 if (feature.values.size() > 0) pitch = feature.values[0];
446
447 float duration = 1;
448 if (feature.values.size() > 1) duration = feature.values[1];
449
450 float velocity = 100;
451 if (feature.values.size() > 2) velocity = feature.values[2];
452
453 NoteModel *model = getOutput<NoteModel>();
454 if (!model) return;
455
456 model->addPoint(NoteModel::Point(frame, pitch, duration, feature.label.c_str()));
428 457
429 } else { 458 } else {
430 459
431 DenseThreeDimensionalModel::BinValueSet values = feature.values; 460 DenseThreeDimensionalModel::BinValueSet values = feature.values;
432 461
449 478
450 SparseOneDimensionalModel *model = getOutput<SparseOneDimensionalModel>(); 479 SparseOneDimensionalModel *model = getOutput<SparseOneDimensionalModel>();
451 if (!model) return; 480 if (!model) return;
452 model->setCompletion(completion); 481 model->setCompletion(completion);
453 482
454 } else if (binCount == 1 || 483 } else if (binCount == 1) {
455 m_descriptor->sampleType == 484
485 SparseTimeValueModel *model = getOutput<SparseTimeValueModel>();
486 if (!model) return;
487 model->setCompletion(completion);
488
489 } else if (m_descriptor->sampleType ==
456 Vamp::Plugin::OutputDescriptor::VariableSampleRate) { 490 Vamp::Plugin::OutputDescriptor::VariableSampleRate) {
457 491
458 SparseTimeValueModel *model = getOutput<SparseTimeValueModel>(); 492 NoteModel *model = getOutput<NoteModel>();
459 if (!model) return; 493 if (!model) return;
460 model->setCompletion(completion); 494 model->setCompletion(completion);
461 495
462 } else { 496 } else {
463 497