# HG changeset patch # User Chris Cannam # Date 1385116648 0 # Node ID 226733f3cf3fcf1fd634f3f6230b12d050cf62ae # Parent f63051833723ad9a4fd56ce902359fbbe42faefc# Parent e50a8fee67529803a1512d1ddd83eb6a76d853c4 Merge from default branch diff -r e50a8fee6752 -r 226733f3cf3f base/PlayParameterRepository.cpp --- a/base/PlayParameterRepository.cpp Mon Nov 04 15:47:46 2013 +0000 +++ b/base/PlayParameterRepository.cpp Fri Nov 22 10:37:28 2013 +0000 @@ -35,14 +35,14 @@ void PlayParameterRepository::addPlayable(const Playable *playable) { -// std::cerr << "PlayParameterRepository:addPlayable " << playable << std::endl; + std::cerr << "PlayParameterRepository:addPlayable playable = " << playable << std::endl; if (!getPlayParameters(playable)) { // Give all playables the same type of play parameters for the // moment -// std::cerr << "PlayParameterRepository: Adding play parameters for " << playable << std::endl; + std::cerr << "PlayParameterRepository:addPlayable: Adding play parameters for " << playable << std::endl; PlayParameters *params = new PlayParameters; m_playParameters[playable] = params; @@ -62,8 +62,8 @@ connect(params, SIGNAL(playPluginConfigurationChanged(QString)), this, SLOT(playPluginConfigurationChanged(QString))); -// std::cerr << "Connected play parameters " << params << " for playable " -// << playable << " to this " << this << std::endl; + std::cerr << "Connected play parameters " << params << " for playable " + << playable << " to this " << this << std::endl; } } diff -r e50a8fee6752 -r 226733f3cf3f data/fft/FFTDataServer.cpp --- a/data/fft/FFTDataServer.cpp Mon Nov 04 15:47:46 2013 +0000 +++ b/data/fft/FFTDataServer.cpp Fri Nov 22 10:37:28 2013 +0000 @@ -191,7 +191,7 @@ if (server->getFillCompletion() < 50) distance += 100; #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::getFuzzyInstance: Distance for server " << server << " is " << distance << ", best is " << bestdist << endl; + std::cerr << "FFTDataServer::getFuzzyInstance: Distance for server " << server << " is " << distance << ", best is " << bestdist << std::endl; #endif if (bestdist == -1 || distance < bestdist) { @@ -204,7 +204,7 @@ if (bestdist >= 0) { FFTDataServer *server = best->second.first; #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::getFuzzyInstance: We like server " << server << " (with distance " << bestdist << ")" << endl; + std::cerr << "FFTDataServer::getFuzzyInstance: We like server " << server << " (with distance " << bestdist << ")" << std::endl; #endif claimInstance(server, false); return server; @@ -228,7 +228,7 @@ FFTDataServer::findServer(QString n) { #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::findServer(\"" << n << "\")" << endl; + std::cerr << "FFTDataServer::findServer(\"" << n << "\")" << std::endl; #endif if (m_servers.find(n) != m_servers.end()) { @@ -236,7 +236,7 @@ FFTDataServer *server = m_servers[n].first; #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::findServer(\"" << n << "\"): found " << server << endl; + std::cerr << "FFTDataServer::findServer(\"" << n << "\"): found " << server << std::endl; #endif claimInstance(server, false); @@ -245,7 +245,7 @@ } #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::findServer(\"" << n << "\"): not found" << endl; + std::cerr << "FFTDataServer::findServer(\"" << n << "\"): not found" << std::endl; #endif return 0; @@ -264,7 +264,7 @@ "FFTDataServer::claimInstance::m_serverMapMutex"); #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::claimInstance(" << server << ")" << endl; + std::cerr << "FFTDataServer::claimInstance(" << server << ")" << std::endl; #endif for (ServerMap::iterator i = m_servers.begin(); i != m_servers.end(); ++i) { @@ -275,7 +275,7 @@ if (*j == server) { #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::claimInstance: found in released server list, removing from it" << endl; + std::cerr << "FFTDataServer::claimInstance: found in released server list, removing from it" << std::endl; #endif m_releasedServers.erase(j); break; @@ -285,7 +285,7 @@ ++i->second.second; #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::claimInstance: new refcount is " << i->second.second << endl; + std::cerr << "FFTDataServer::claimInstance: new refcount is " << i->second.second << std::endl; #endif return; @@ -309,7 +309,7 @@ "FFTDataServer::releaseInstance::m_serverMapMutex"); #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::releaseInstance(" << server << ")" << endl; + std::cerr << "FFTDataServer::releaseInstance(" << server << ")" << std::endl; #endif // -- if ref count > 0, decrement and return @@ -332,18 +332,18 @@ /*!!! if (server->m_lastUsedCache == -1) { // never used #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::releaseInstance: instance " + std::cerr << "FFTDataServer::releaseInstance: instance " << server << " has never been used, erasing" - << endl; + << std::endl; #endif delete server; m_servers.erase(i); } else { */ #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::releaseInstance: instance " + std::cerr << "FFTDataServer::releaseInstance: instance " << server << " no longer in use, marking for possible collection" - << endl; + << std::endl; #endif bool found = false; for (ServerQueue::iterator j = m_releasedServers.begin(); @@ -361,9 +361,9 @@ //!!! } } else { #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::releaseInstance: instance " + std::cerr << "FFTDataServer::releaseInstance: instance " << server << " now has refcount " << i->second.second - << endl; + << std::endl; #endif } return; @@ -378,8 +378,8 @@ FFTDataServer::purgeLimbo(int maxSize) { #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::purgeLimbo(" << maxSize << "): " - << m_releasedServers.size() << " candidates" << endl; + std::cerr << "FFTDataServer::purgeLimbo(" << maxSize << "): " + << m_releasedServers.size() << " candidates" << std::endl; #endif while (int(m_releasedServers.size()) > maxSize) { @@ -389,8 +389,8 @@ bool found = false; #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::purgeLimbo: considering candidate " - << server << endl; + std::cerr << "FFTDataServer::purgeLimbo: considering candidate " + << server << std::endl; #endif for (ServerMap::iterator i = m_servers.begin(); i != m_servers.end(); ++i) { @@ -405,8 +405,8 @@ break; } #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::purgeLimbo: looks OK, erasing it" - << endl; + std::cerr << "FFTDataServer::purgeLimbo: looks OK, erasing it" + << std::endl; #endif m_servers.erase(i); @@ -426,8 +426,8 @@ } #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::purgeLimbo(" << maxSize << "): " - << m_releasedServers.size() << " remain" << endl; + std::cerr << "FFTDataServer::purgeLimbo(" << maxSize << "): " + << m_releasedServers.size() << " remain" << std::endl; #endif } @@ -439,8 +439,8 @@ "FFTDataServer::modelAboutToBeDeleted::m_serverMapMutex"); #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::modelAboutToBeDeleted(" << model << ")" - << endl; + std::cerr << "FFTDataServer::modelAboutToBeDeleted(" << model << ")" + << std::endl; #endif for (ServerMap::iterator i = m_servers.begin(); i != m_servers.end(); ++i) { @@ -450,8 +450,8 @@ if (server->getModel() == model) { #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::modelAboutToBeDeleted: server is " - << server << endl; + std::cerr << "FFTDataServer::modelAboutToBeDeleted: server is " + << server << std::endl; #endif if (i->second.second > 0) { @@ -463,14 +463,14 @@ j != m_releasedServers.end(); ++j) { if (*j == server) { #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::modelAboutToBeDeleted: erasing from released servers" << endl; + std::cerr << "FFTDataServer::modelAboutToBeDeleted: erasing from released servers" << std::endl; #endif m_releasedServers.erase(j); break; } } #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::modelAboutToBeDeleted: erasing server" << endl; + std::cerr << "FFTDataServer::modelAboutToBeDeleted: erasing server" << std::endl; #endif m_servers.erase(i); delete server; @@ -841,7 +841,7 @@ // preconditions: m_caches[c] exists and contains a file writer; // m_cacheVectorLock is not locked by this thread #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::makeCacheReader(" << c << ")" << endl; + std::cerr << "FFTDataServer::makeCacheReader(" << c << ")" << std::endl; #endif QThread *me = QThread::currentThread(); @@ -875,7 +875,7 @@ cb = m_caches.at(deleteCandidate); if (cb && cb->fileCacheReader.find(me) != cb->fileCacheReader.end()) { #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::makeCacheReader: Deleting probably unpopular reader " << deleteCandidate << " for this thread (as I create reader " << c << ")" << endl; + std::cerr << "FFTDataServer::makeCacheReader: Deleting probably unpopular reader " << deleteCandidate << " for this thread (as I create reader " << c << ")" << std::endl; #endif delete cb->fileCacheReader[me]; cb->fileCacheReader.erase(me); @@ -901,8 +901,8 @@ if (!cache->haveSetColumnAt(col)) { Profiler profiler("FFTDataServer::getMagnitudeAt: filling"); #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::getMagnitudeAt: calling fillColumn(" - << x << ")" << endl; + std::cerr << "FFTDataServer::getMagnitudeAt: calling fillColumn(" + << x << ")" << std::endl; #endif fillColumn(x); } @@ -1130,7 +1130,7 @@ if (!cache->haveSetColumnAt(col)) { Profiler profiler("FFTDataServer::getValuesAt: filling"); #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::getValuesAt(" << x << ", " << y << "): filling" << endl; + std::cerr << "FFTDataServer::getValuesAt(" << x << ", " << y << "): filling" << std::endl; #endif fillColumn(x); } @@ -1189,7 +1189,7 @@ /*!!! if (m_lastUsedCache == -1) { if (m_suspended) { - SVDEBUG << "FFTDataServer::isColumnReady(" << x << "): no cache, calling resume" << endl; + std::cerr << "FFTDataServer::isColumnReady(" << x << "): no cache, calling resume" << std::endl; resume(); } m_fillThread->start(); @@ -1258,12 +1258,12 @@ endFrame -= winsize / 2; #ifdef DEBUG_FFT_SERVER_FILL - SVDEBUG << "FFTDataServer::fillColumn: requesting frames " + std::cerr << "FFTDataServer::fillColumn: requesting frames " << startFrame + pfx << " -> " << endFrame << " ( = " << endFrame - (startFrame + pfx) << ") at index " << off + pfx << " in buffer of size " << m_fftSize << " with window size " << m_windowSize - << " from channel " << m_channel << endl; + << " from channel " << m_channel << std::endl; #endif QMutexLocker locker(&m_fftBuffersLock); @@ -1370,7 +1370,7 @@ } if (m_suspended) { -// SVDEBUG << "FFTDataServer::fillColumn(" << x << "): calling resume" << endl; +// std::cerr << "FFTDataServer::fillColumn(" << x << "): calling resume" << std::endl; // resume(); } } @@ -1446,7 +1446,7 @@ FFTDataServer::FillThread::run() { #ifdef DEBUG_FFT_SERVER_FILL - SVDEBUG << "FFTDataServer::FillThread::run()" << endl; + std::cerr << "FFTDataServer::FillThread::run()" << std::endl; #endif m_extent = 0; @@ -1454,7 +1454,7 @@ while (!m_server.m_model->isReady() && !m_server.m_exiting) { #ifdef DEBUG_FFT_SERVER_FILL - SVDEBUG << "FFTDataServer::FillThread::run(): waiting for model " << m_server.m_model << " to be ready" << endl; + std::cerr << "FFTDataServer::FillThread::run(): waiting for model " << m_server.m_model << " to be ready" << std::endl; #endif sleep(1); } @@ -1476,7 +1476,7 @@ try { m_server.fillColumn(int((f - start) / m_server.m_windowIncrement)); } catch (std::exception &e) { - SVDEBUG << "FFTDataServer::FillThread::run: exception: " << e.what() << endl; + std::cerr << "FFTDataServer::FillThread::run: exception: " << e.what() << std::endl; m_error = e.what(); m_server.fillComplete(); m_completion = 100; @@ -1525,7 +1525,7 @@ try { m_server.fillColumn(int((f - start) / m_server.m_windowIncrement)); } catch (std::exception &e) { - SVDEBUG << "FFTDataServer::FillThread::run: exception: " << e.what() << endl; + std::cerr << "FFTDataServer::FillThread::run: exception: " << e.what() << std::endl; m_error = e.what(); m_server.fillComplete(); m_completion = 100; @@ -1567,7 +1567,7 @@ m_extent = end; #ifdef DEBUG_FFT_SERVER - SVDEBUG << "FFTDataServer::FillThread::run exiting" << endl; + std::cerr << "FFTDataServer::FillThread::run exiting" << std::endl; #endif } diff -r e50a8fee6752 -r 226733f3cf3f data/fileio/CoreAudioFileReader.cpp --- a/data/fileio/CoreAudioFileReader.cpp Mon Nov 04 15:47:46 2013 +0000 +++ b/data/fileio/CoreAudioFileReader.cpp Fri Nov 22 10:37:28 2013 +0000 @@ -89,16 +89,16 @@ //!!! how do we find out if the file open fails because of DRM protection? -#if (MACOSX_DEPLOYMENT_TARGET <= 1040 && MAC_OS_X_VERSION_MIN_REQUIRED <= 1040) - FSRef fsref; - if (!CFURLGetFSRef(url, &fsref)) { // returns Boolean, not error code - m_error = "CoreAudioReadStream: Error looking up FS ref (file not found?)"; - return; - } - m_d->err = ExtAudioFileOpen(&fsref, &m_d->file); -#else +//#if (MACOSX_DEPLOYMENT_TARGET <= 1040 && MAC_OS_X_VERSION_MIN_REQUIRED <= 1040) +// FSRef fsref; +// if (!CFURLGetFSRef(url, &fsref)) { // returns Boolean, not error code +// m_error = "CoreAudioReadStream: Error looking up FS ref (file not found?)"; +// return; +// } +// m_d->err = ExtAudioFileOpen(&fsref, &m_d->file); +//#else m_d->err = ExtAudioFileOpenURL(url, &m_d->file); -#endif +//#endif CFRelease(url); diff -r e50a8fee6752 -r 226733f3cf3f data/model/FlexiNoteModel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/model/FlexiNoteModel.h Fri Nov 22 10:37:28 2013 +0000 @@ -0,0 +1,234 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006 Chris Cannam. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef _FLEXINOTE_MODEL_H_ +#define _FLEXINOTE_MODEL_H_ + +// #include "NotelikeModel.h" // GF: reomved as this is an uncommitted experiment for now + +#include "IntervalModel.h" +#include "base/RealTime.h" +#include "base/PlayParameterRepository.h" + +/** + * FlexiNoteModel -- a concrete IntervalModel for notes. + */ + +/** + * Extension of the NoteModel for more flexible note interaction. + * The original NoteModel rationale is given below, will need to be + * updated for FlexiNoteModel: + * + * Note type for use in a sparse model. All we mean by a "note" is + * something that has an onset time, a single value, a duration, and a + * level. Like other points, it can also have a label. With this + * point type, the model can be thought of as representing a simple + * MIDI-type piano roll, except that the y coordinates (values) do not + * have to be discrete integers. + */ + +struct FlexiNote +{ +public: + FlexiNote(long _frame) : frame(_frame), value(0.0f), duration(0), level(1.f) { } + FlexiNote(long _frame, float _value, size_t _duration, float _level, QString _label) : + frame(_frame), value(_value), duration(_duration), level(_level), label(_label) { } + + int getDimensions() const { return 3; } + + long frame; + float value; + size_t duration; + float level; + QString label; + + QString getLabel() const { return label; } + + void toXml(QTextStream &stream, + QString indent = "", + QString extraAttributes = "") const + { + stream << + QString("%1\n") + .arg(indent).arg(frame).arg(value).arg(duration).arg(level) + .arg(XmlExportable::encodeEntities(label)).arg(extraAttributes); + } + + QString toDelimitedDataString(QString delimiter, size_t sampleRate) const + { + QStringList list; + list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str(); + list << QString("%1").arg(value); + list << RealTime::frame2RealTime(duration, sampleRate).toString().c_str(); + list << QString("%1").arg(level); + if (label != "") list << label; + return list.join(delimiter); + } + + struct Comparator { + bool operator()(const FlexiNote &p1, + const FlexiNote &p2) const { + if (p1.frame != p2.frame) return p1.frame < p2.frame; + if (p1.value != p2.value) return p1.value < p2.value; + if (p1.duration != p2.duration) return p1.duration < p2.duration; + if (p1.level != p2.level) return p1.level < p2.level; + return p1.label < p2.label; + } + }; + + struct OrderComparator { + bool operator()(const FlexiNote &p1, + const FlexiNote &p2) const { + return p1.frame < p2.frame; + } + }; +}; + + +class FlexiNoteModel : public IntervalModel +{ + Q_OBJECT + +public: + FlexiNoteModel(size_t sampleRate, size_t resolution, + bool notifyOnAdd = true) : + IntervalModel(sampleRate, resolution, notifyOnAdd), + m_valueQuantization(0) + { + PlayParameterRepository::getInstance()->addPlayable(this); + } + + FlexiNoteModel(size_t sampleRate, size_t resolution, + float valueMinimum, float valueMaximum, + bool notifyOnAdd = true) : + IntervalModel(sampleRate, resolution, + valueMinimum, valueMaximum, + notifyOnAdd), + m_valueQuantization(0) + { + PlayParameterRepository::getInstance()->addPlayable(this); + } + + virtual ~FlexiNoteModel() + { + PlayParameterRepository::getInstance()->removePlayable(this); + } + + float getValueQuantization() const { return m_valueQuantization; } + void setValueQuantization(float q) { m_valueQuantization = q; } + float getValueMinimum() const { return 33; } + float getValueMaximum() const { return 88; } + + QString getTypeName() const { return tr("FlexiNote"); } + + virtual bool canPlay() const { return true; } + + virtual QString getDefaultPlayPluginId() const + { + return "dssi:_builtin:sample_player"; + } + + virtual QString getDefaultPlayPluginConfiguration() const + { + return ""; + } + + virtual void toXml(QTextStream &out, + QString indent = "", + QString extraAttributes = "") const + { + std::cerr << "FlexiNoteModel::toXml: extraAttributes = \"" + << extraAttributes.toStdString() << std::endl; + + IntervalModel::toXml + (out, + indent, + QString("%1 subtype=\"note\" valueQuantization=\"%2\"") + .arg(extraAttributes).arg(m_valueQuantization)); + } + + /** + * TabularModel methods. + */ + + virtual int getColumnCount() const + { + return 6; + } + + virtual QString getHeading(int column) const + { + switch (column) { + case 0: return tr("Time"); + case 1: return tr("Frame"); + case 2: return tr("Pitch"); + case 3: return tr("Duration"); + case 4: return tr("Level"); + case 5: return tr("Label"); + default: return tr("Unknown"); + } + } + + virtual QVariant getData(int row, int column, int role) const + { + if (column < 4) { + return IntervalModel::getData(row, column, role); + } + + PointListConstIterator i = getPointListIteratorForRow(row); + if (i == m_points.end()) return QVariant(); + + switch (column) { + case 4: return i->level; + case 5: return i->label; + default: return QVariant(); + } + } + + virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role) + { + if (column < 4) { + return IntervalModel::getSetDataCommand + (row, column, value, role); + } + + if (role != Qt::EditRole) return 0; + PointListConstIterator i = getPointListIteratorForRow(row); + if (i == m_points.end()) return 0; + EditCommand *command = new EditCommand(this, tr("Edit Data")); + + Point point(*i); + command->deletePoint(point); + + switch (column) { + case 4: point.level = value.toDouble(); break; + case 5: point.label = value.toString(); break; + } + + command->addPoint(point); + return command->finish(); + } + + virtual SortType getSortType(int column) const + { + if (column == 5) return SortAlphabetical; + return SortNumeric; + } + +protected: + float m_valueQuantization; +}; + +#endif diff -r e50a8fee6752 -r 226733f3cf3f plugin/DSSIPluginInstance.cpp --- a/plugin/DSSIPluginInstance.cpp Mon Nov 04 15:47:46 2013 +0000 +++ b/plugin/DSSIPluginInstance.cpp Fri Nov 22 10:37:28 2013 +0000 @@ -34,7 +34,7 @@ #endif //#define DEBUG_DSSI 1 -//#define DEBUG_DSSI_PROCESS 1 +#define DEBUG_DSSI_PROCESS 1 #define EVENT_BUFFER_SIZE 1023 diff -r e50a8fee6752 -r 226733f3cf3f plugin/plugins/SamplePlayer.cpp --- a/plugin/plugins/SamplePlayer.cpp Mon Nov 04 15:47:46 2013 +0000 +++ b/plugin/plugins/SamplePlayer.cpp Fri Nov 22 10:37:28 2013 +0000 @@ -157,6 +157,7 @@ } SamplePlayer *player = new SamplePlayer(rate); + // std::cerr << "Instantiated sample player " << std::endl; if (hostDescriptor->request_non_rt_thread(player, workThreadCallback)) { SVDEBUG << "SamplePlayer::instantiate: Host rejected request_non_rt_thread call, not instantiating" << endl; diff -r e50a8fee6752 -r 226733f3cf3f svcore.pro --- a/svcore.pro Mon Nov 04 15:47:46 2013 +0000 +++ b/svcore.pro Fri Nov 22 10:37:28 2013 +0000 @@ -155,6 +155,7 @@ data/model/Model.h \ data/model/ModelDataTableModel.h \ data/model/NoteModel.h \ + data/model/FlexiNoteModel.h \ data/model/PathModel.h \ data/model/PowerOfSqrtTwoZoomConstraint.h \ data/model/PowerOfTwoZoomConstraint.h \ diff -r e50a8fee6752 -r 226733f3cf3f transform/FeatureExtractionModelTransformer.cpp --- a/transform/FeatureExtractionModelTransformer.cpp Mon Nov 04 15:47:46 2013 +0000 +++ b/transform/FeatureExtractionModelTransformer.cpp Fri Nov 22 10:37:28 2013 +0000 @@ -27,6 +27,7 @@ #include "data/model/EditableDenseThreeDimensionalModel.h" #include "data/model/DenseTimeValueModel.h" #include "data/model/NoteModel.h" +#include "data/model/FlexiNoteModel.h" #include "data/model/RegionModel.h" #include "data/model/FFTModel.h" #include "data/model/WaveFileModel.h" @@ -37,12 +38,14 @@ #include FeatureExtractionModelTransformer::FeatureExtractionModelTransformer(Input in, - const Transform &transform) : + const Transform &transform, + const PreferredOutputModel outputmodel) : ModelTransformer(in, transform), m_plugin(0), m_descriptor(0), m_outputNo(0), - m_fixedRateFeatureNo(-1) // we increment before use + m_fixedRateFeatureNo(-1), // we increment before use + m_preferredOutputModel(outputmodel) { // SVDEBUG << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: plugin " << pluginId << ", outputName " << m_transform.getOutput() << endl; @@ -295,15 +298,25 @@ // problem of determining whether to use that here (if bin // count > 1). But we don't. - if (isNoteModel) { + if (isNoteModel && m_preferredOutputModel == NoteOutputModel) { NoteModel *model; if (haveExtents) { - model = new NoteModel - (modelRate, modelResolution, minValue, maxValue, false); + model = new NoteModel (modelRate, modelResolution, minValue, maxValue, false); } else { - model = new NoteModel - (modelRate, modelResolution, false); + model = new NoteModel (modelRate, modelResolution, false); + } + model->setScaleUnits(m_descriptor->unit.c_str()); + m_output = model; + + // GF: FlexiNoteModel is selected if the m_preferredOutputModel is set + } else if (isNoteModel && m_preferredOutputModel == FlexiNoteOutputModel) { + + FlexiNoteModel *model; + if (haveExtents) { + model = new FlexiNoteModel (modelRate, modelResolution, minValue, maxValue, false); + } else { + model = new FlexiNoteModel (modelRate, modelResolution, false); } model->setScaleUnits(m_descriptor->unit.c_str()); m_output = model; @@ -715,7 +728,7 @@ model->addPoint(SparseTimeValueModel::Point(frame, value, label)); } - } else if (isOutput() || isOutput()) { + } else if (isOutput() || isOutput() || isOutput()) { //GF: Added Note Model int index = 0; @@ -732,8 +745,24 @@ duration = feature.values[index++]; } } - - if (isOutput()) { + + if (isOutput()) { // GF: added for flexi note model + + float velocity = 100; + if (feature.values.size() > index) { + velocity = feature.values[index++]; + } + if (velocity < 0) velocity = 127; + if (velocity > 127) velocity = 127; + + FlexiNoteModel *model = getConformingOutput(); + if (!model) return; + model->addPoint(FlexiNoteModel::Point(frame, value, // value is pitch + lrintf(duration), + velocity / 127.f, + feature.label.c_str())); + // GF: end -- added for flexi note model + } else if (isOutput()) { float velocity = 100; if (feature.values.size() > index) { @@ -749,6 +778,7 @@ velocity / 127.f, feature.label.c_str())); } else { + RegionModel *model = getConformingOutput(); if (!model) return; @@ -821,6 +851,12 @@ NoteModel *model = getConformingOutput(); if (!model) return; model->setCompletion(completion, true); + + } else if (isOutput()) { + + FlexiNoteModel *model = getConformingOutput(); + if (!model) return; + model->setCompletion(completion, true); } else if (isOutput()) { diff -r e50a8fee6752 -r 226733f3cf3f transform/FeatureExtractionModelTransformer.h --- a/transform/FeatureExtractionModelTransformer.h Mon Nov 04 15:47:46 2013 +0000 +++ b/transform/FeatureExtractionModelTransformer.h Fri Nov 22 10:37:28 2013 +0000 @@ -31,8 +31,16 @@ Q_OBJECT public: + enum PreferredOutputModel { + NoteOutputModel, + FlexiNoteOutputModel, + UndefinedOutputModel = 255 + }; + FeatureExtractionModelTransformer(Input input, - const Transform &transform); + const Transform &transform, + const PreferredOutputModel outputmodel); + virtual ~FeatureExtractionModelTransformer(); protected: @@ -42,6 +50,7 @@ Vamp::Plugin::OutputDescriptor *m_descriptor; int m_fixedRateFeatureNo; // to assign times to FixedSampleRate features int m_outputNo; + PreferredOutputModel m_preferredOutputModel; void createOutputModel(); diff -r e50a8fee6752 -r 226733f3cf3f transform/ModelTransformerFactory.cpp --- a/transform/ModelTransformerFactory.cpp Mon Nov 04 15:47:46 2013 +0000 +++ b/transform/ModelTransformerFactory.cpp Fri Nov 22 10:37:28 2013 +0000 @@ -173,7 +173,7 @@ if (FeatureExtractionPluginFactory::instanceFor(id)) { transformer = - new FeatureExtractionModelTransformer(input, transform); + new FeatureExtractionModelTransformer(input, transform, m_preferredOutputModel); } else if (RealTimePluginFactory::instanceFor(id)) { @@ -193,10 +193,13 @@ Model * ModelTransformerFactory::transform(const Transform &transform, const ModelTransformer::Input &input, - QString &message) + QString &message, + /* outputmodel default value = FeatureExtractionModelTransformer::NoteOutputModel */ + FeatureExtractionModelTransformer::PreferredOutputModel outputmodel) { SVDEBUG << "ModelTransformerFactory::transform: Constructing transformer with input model " << input.getModel() << endl; + m_preferredOutputModel = outputmodel; ModelTransformer *t = createTransformer(transform, input); if (!t) return 0; diff -r e50a8fee6752 -r 226733f3cf3f transform/ModelTransformerFactory.h --- a/transform/ModelTransformerFactory.h Mon Nov 04 15:47:46 2013 +0000 +++ b/transform/ModelTransformerFactory.h Fri Nov 22 10:37:28 2013 +0000 @@ -18,6 +18,7 @@ #include "Transform.h" #include "TransformDescription.h" +#include "FeatureExtractionModelTransformer.h" #include "ModelTransformer.h" @@ -83,9 +84,10 @@ * The returned model is owned by the caller and must be deleted * when no longer needed. */ - Model *transform(const Transform &transform, - const ModelTransformer::Input &input, - QString &message); + Model *transform(const Transform &transform, + const ModelTransformer::Input &input, + QString &message, + const FeatureExtractionModelTransformer::PreferredOutputModel outputmodel = FeatureExtractionModelTransformer::NoteOutputModel); protected slots: void transformerFinished(); @@ -103,6 +105,11 @@ TransformerSet m_runningTransformers; static ModelTransformerFactory *m_instance; + /** + * allows the FeatureExtractionModelTransformer output model to be selected externally, + * but only in case of the need for NoteModel or FlexiNoteModel + */ + FeatureExtractionModelTransformer::PreferredOutputModel m_preferredOutputModel ; };