Mercurial > hg > svapp
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); }