changeset 290:a3fcaad1a269 tonioni

Merge from the default branch
author Chris Cannam
date Fri, 12 Jul 2013 13:26:41 +0100
parents cba1e2a3d14b (diff) 2925a4bbca5e (current diff)
children bc78f88a66f5
files framework/MainWindowBase.cpp
diffstat 6 files changed, 170 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/audioio/AudioCallbackPlaySource.cpp	Tue Jul 09 11:44:51 2013 +0100
+++ b/audioio/AudioCallbackPlaySource.cpp	Fri Jul 12 13:26:41 2013 +0100
@@ -164,7 +164,7 @@
     }
 
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
-    std::cout << "Adding model with " << modelChannels << " channels at rate " << model->getSampleRate() << std::endl;
+    std::cout << "AudioCallbackPlaySource.cpp: Adding model with " << modelChannels << " channels at rate " << model->getSampleRate() << std::endl;
 #endif
 
     if (m_sourceSampleRate == 0) {
--- a/audioio/AudioGenerator.cpp	Tue Jul 09 11:44:51 2013 +0100
+++ b/audioio/AudioGenerator.cpp	Fri Jul 12 13:26:41 2013 +0100
@@ -22,6 +22,7 @@
 #include "base/Exceptions.h"
 
 #include "data/model/NoteModel.h"
+#include "data/model/FlexiNoteModel.h"
 #include "data/model/DenseTimeValueModel.h"
 #include "data/model/SparseOneDimensionalModel.h"
 
@@ -204,11 +205,19 @@
         configurationXml = parameters->getPlayPluginConfiguration();
     }
 
-    if (pluginId == "") return 0;
+    std::cerr << "AudioGenerator::loadPluginFor(" << model << "): id = " << pluginId << std::endl;
+
+    if (pluginId == "") {
+        SVDEBUG << "AudioGenerator::loadPluginFor(" << model << "): parameters contain empty plugin ID, skipping" << endl;
+        return 0;
+    }
 
     RealTimePluginInstance *plugin = loadPlugin(pluginId, "");
     if (!plugin) return 0;
 
+    std::cerr << "AudioGenerator::loadPluginFor(" << model << "): loaded plugin "
+              << plugin << std::endl;
+
     if (configurationXml != "") {
         PluginXml(plugin).setParametersFromXml(configurationXml);
         setSampleDir(plugin);
@@ -251,11 +260,11 @@
     }
     std::string defaultProgram = instance->getProgram(0, 0);
     if (defaultProgram != "") {
-//        std::cerr << "first selecting default program " << defaultProgram << std::endl;
+        std::cerr << "first selecting default program " << defaultProgram << std::endl;
         instance->selectProgram(defaultProgram);
     }
     if (program != "") {
-//        std::cerr << "now selecting desired program " << program << std::endl;
+        std::cerr << "now selecting desired program " << program << std::endl;
         instance->selectProgram(program.toStdString());
     }
     instance->setIdealChannelCount(m_targetChannelCount); // reset!
@@ -389,13 +398,16 @@
 
     bool synthetic = 
         (qobject_cast<SparseOneDimensionalModel *>(model) ||
-         qobject_cast<NoteModel *>(model));
+         qobject_cast<NoteModel *>(model) ||
+         qobject_cast<FlexiNoteModel *>(model));
 
     if (synthetic) {
         return mixSyntheticNoteModel(model, startFrame, frameCount,
                                      buffer, gain, pan, fadeIn, fadeOut);
     }
 
+    std::cerr << "AudioGenerator::mixModel: WARNING: Model " << model << " of type " << model->getTypeName() << " is marked as playable, but I have no mechanism to play it" << std::endl;
+
     return frameCount;
 }
 
@@ -708,6 +720,45 @@
         return notes;
     }
 
+    FlexiNoteModel *fnm = qobject_cast<FlexiNoteModel *>(model);
+
+    if (fnm) {
+        
+        // currently identical to NoteModel case above
+
+	FlexiNoteModel::PointList points =
+	    fnm->getPoints(startFrame, endFrame);
+
+        for (FlexiNoteModel::PointList::iterator pli =
+		 points.begin(); pli != points.end(); ++pli) {
+
+	    size_t duration = pli->duration;
+            if (duration == 0 || duration == 1) {
+                duration = m_sourceSampleRate / 20;
+            }
+
+            int pitch = lrintf(pli->value);
+
+            int velocity = 100;
+            if (pli->level > 0.f && pli->level <= 1.f) {
+                velocity = lrintf(pli->level * 127);
+            }
+
+            NoteData note(pli->frame,
+                          duration,
+                          pitch,
+                          velocity);
+
+            if (fnm->getScaleUnits() == "Hz") {
+                note.frequency = pli->value;
+                note.isMidiPitchQuantized = false;
+            }
+        
+            notes.push_back(note);
+        }
+
+        return notes;
+    }
+
     return notes;
 }
-
--- a/audioio/AudioGenerator.h	Tue Jul 09 11:44:51 2013 +0100
+++ b/audioio/AudioGenerator.h	Fri Jul 12 13:26:41 2013 +0100
@@ -18,6 +18,7 @@
 
 class Model;
 class NoteModel;
+class FlexiNoteModel;
 class DenseTimeValueModel;
 class SparseOneDimensionalModel;
 class RealTimePluginInstance;
--- a/framework/Document.cpp	Tue Jul 09 11:44:51 2013 +0100
+++ b/framework/Document.cpp	Fri Jul 12 13:26:41 2013 +0100
@@ -19,6 +19,8 @@
 #include "data/model/WritableWaveFileModel.h"
 #include "data/model/DenseThreeDimensionalModel.h"
 #include "data/model/DenseTimeValueModel.h"
+#include "data/model/FlexiNoteModel.h"
+
 #include "layer/Layer.h"
 #include "widgets/CommandHistory.h"
 #include "base/Command.h"
@@ -27,6 +29,7 @@
 #include "base/PlayParameters.h"
 #include "transform/TransformFactory.h"
 #include "transform/ModelTransformerFactory.h"
+#include "transform/FeatureExtractionModelTransformer.h"
 #include <QApplication>
 #include <QTextStream>
 #include <QSettings>
@@ -202,7 +205,6 @@
 
     return newLayer;
 }
-
 Layer *
 Document::createDerivedLayer(const Transform &transform,
                              const ModelTransformer::Input &input)
@@ -259,6 +261,67 @@
     return newLayer;
 }
 
+Layer *
+Document::createDerivedLayer(const Transform &transform,
+                             const ModelTransformer::Input &input,
+                             const LayerFactory::LayerType type,
+							 const FeatureExtractionModelTransformer::PreferredOutputModel outputmodel)
+{
+	// !!! THIS IS TOTALLY REDUNDANT CODE, EXCEPT FOR THE type SETTING
+	
+	    QString message;
+	    Model *newModel = addDerivedModel(transform, input, message, outputmodel);
+	    if (!newModel) {
+	        emit modelGenerationFailed(transform.getIdentifier(), message);
+	        return 0;
+	    } else if (message != "") {
+	        emit modelGenerationWarning(transform.getIdentifier(), message);
+	    }
+	
+	    LayerFactory::LayerTypeSet types =
+	LayerFactory::getInstance()->getValidLayerTypes(newModel);
+	
+	    if (types.empty()) {
+	std::cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transform.getIdentifier() << std::endl;
+	        newModel->aboutToDelete();
+	        emit modelAboutToBeDeleted(newModel);
+	        m_models.erase(newModel);
+	delete newModel;
+	return 0;
+	    }
+
+    //!!! creating layer with the specified type
+
+    Layer *newLayer = createLayer(type);
+    setModel(newLayer, newModel);
+
+    //!!! We need to clone the model when adding the layer, so that it
+    //can be edited without affecting other layers that are based on
+    //the same model.  Unfortunately we can't just clone it now,
+    //because it probably hasn't been completed yet -- the transform
+    //runs in the background.  Maybe the transform has to handle
+    //cloning and cacheing models itself.
+    //
+    // Once we do clone models here, of course, we'll have to avoid
+    // leaking them too.
+    //
+    // We want the user to be able to add a model to a second layer
+    // _while it's still being calculated in the first_ and have it
+    // work quickly.  That means we need to put the same physical
+    // model pointer in both layers, so they can't actually be cloned.
+    
+    if (newLayer) {
+	newLayer->setObjectName(getUniqueLayerName
+                                (TransformFactory::getInstance()->
+                                 getTransformFriendlyName
+                                 (transform.getIdentifier())));
+    }
+
+    emit layerAdded(newLayer);
+    return newLayer;
+}
+
+
 void
 Document::setMainModel(WaveFileModel *model)
 {
@@ -501,20 +564,25 @@
 Model *
 Document::addDerivedModel(const Transform &transform,
                           const ModelTransformer::Input &input,
-                          QString &message)
+                          QString &message,
+						  const FeatureExtractionModelTransformer::PreferredOutputModel outputmodel)
 {
     Model *model = 0;
+	// model = (Model) new FlexiNoteModel();
+	// return model;
 
     for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
 	if (i->second.transform == transform &&
 	    i->second.source == input.getModel() && 
             i->second.channel == input.getChannel()) {
+				std::cerr << "derived model taken from map " << std::endl;
 	    return i->first;
 	}
     }
 
+	// GF: TODO: propagate preferredOutputModelSelection (done)
     model = ModelTransformerFactory::getInstance()->transform
-        (transform, input, message);
+        (transform, input, message, outputmodel); //e.g. FeatureExtractionModelTransformer::FlexiNoteOutputModel
 
     // The transform we actually used was presumably identical to the
     // one asked for, except that the version of the plugin may
@@ -535,7 +603,8 @@
     } else {
 	addDerivedModel(applied, input, model);
     }
-
+	// std::cerr << "derived model name: " << model->getTypeName() << std::endl;
+	
     return model;
 }
 
@@ -690,6 +759,7 @@
     }
 
     LayerFactory::getInstance()->setModel(layer, model);
+	// std::cerr << "layer type: " << LayerFactory::getInstance()->getLayerTypeName(LayerFactory::getInstance()->getLayerType(layer)) << std::endl;
 
     if (previousModel) {
         releaseModel(previousModel);
--- a/framework/Document.h	Tue Jul 09 11:44:51 2013 +0100
+++ b/framework/Document.h	Fri Jul 12 13:26:41 2013 +0100
@@ -19,6 +19,7 @@
 #include "layer/LayerFactory.h"
 #include "transform/Transform.h"
 #include "transform/ModelTransformer.h"
+#include "transform/FeatureExtractionModelTransformer.h"
 #include "base/Command.h"
 
 #include <map>
@@ -117,6 +118,17 @@
                               const ModelTransformer::Input &);
 
     /**
+     * Exactly the same as above, but providing exactly the layer type
+     * for cases in which the first suitable layer type for a transform
+     * is not the desired one.
+     * WARNING: highly redundant code (with the above creation funciotn)
+     */
+    Layer *createDerivedLayer(const Transform &,
+                              const ModelTransformer::Input &,
+                              const LayerFactory::LayerType type, 
+							  const FeatureExtractionModelTransformer::PreferredOutputModel outputmodel);
+
+    /**
      * Delete the given layer, and also its associated model if no
      * longer used by any other layer.  In general, this should be the
      * only method used to delete layers -- doing so directly is a bit
@@ -148,10 +160,12 @@
     /**
      * Add a derived model associated with the given transform,
      * running the transform and returning the resulting model.
+	 * In case the output model is a NoteModel, the preferred output model will be selected: {NoteModel | FlexiNoteModel}.
      */
     Model *addDerivedModel(const Transform &transform,
                            const ModelTransformer::Input &input,
-                           QString &returnedMessage);
+                           QString &returnedMessage,
+						   FeatureExtractionModelTransformer::PreferredOutputModel outputmodel = FeatureExtractionModelTransformer::NoteOutputModel);
 
     /**
      * Add a derived model associated with the given transform.  This
--- a/framework/MainWindowBase.cpp	Tue Jul 09 11:44:51 2013 +0100
+++ b/framework/MainWindowBase.cpp	Fri Jul 12 13:26:41 2013 +0100
@@ -22,6 +22,7 @@
 #include "data/model/WaveFileModel.h"
 #include "data/model/SparseOneDimensionalModel.h"
 #include "data/model/NoteModel.h"
+#include "data/model/FlexiNoteModel.h"
 #include "data/model/Labeller.h"
 #include "data/model/TabularModel.h"
 #include "view/ViewManager.h"
@@ -35,6 +36,7 @@
 #include "layer/SliceableLayer.h"
 #include "layer/ImageLayer.h"
 #include "layer/NoteLayer.h"
+#include "layer/FlexiNoteLayer.h"
 #include "layer/RegionLayer.h"
 
 #include "widgets/ListInputDialog.h"
@@ -424,6 +426,7 @@
     bool haveCurrentDurationLayer = 
 	(haveCurrentLayer &&
 	 (dynamic_cast<NoteLayer *>(currentLayer) ||
+	  dynamic_cast<FlexiNoteLayer *>(currentLayer) ||
           dynamic_cast<RegionLayer *>(currentLayer)));
     bool haveCurrentColour3DPlot =
         (haveCurrentLayer &&
@@ -1009,6 +1012,25 @@
         CommandHistory::getInstance()->addCommand(c, false);
         return;
     }
+
+    FlexiNoteModel *fnm = dynamic_cast<FlexiNoteModel *>(layer->getModel());
+    if (fnm) {
+        FlexiNoteModel::Point point(alignedStart,
+                               rm->getValueMinimum(),
+                               alignedDuration,
+                               1.f,
+                               "");
+        FlexiNoteModel::EditCommand *command =
+            new FlexiNoteModel::EditCommand(fnm, tr("Add Point"));
+        command->addPoint(point);
+        command->setName(name);
+        c = command->finish();
+    }
+
+    if (c) {
+        CommandHistory::getInstance()->addCommand(c, false);
+        return;
+    }
 }
 
 void
@@ -3085,6 +3107,7 @@
 MainWindowBase::modelAdded(Model *model)
 {
 //    SVDEBUG << "MainWindowBase::modelAdded(" << model << ")" << endl;
+	std::cerr << "\nAdding model " << model->getTypeName() << " to playsource " << std::endl;
     m_playSource->addModel(model);
 }