annotate transform/TransformFactory.cpp @ 52:d397ea0a79f5

* Update licensing rubric for GPL
author Chris Cannam
date Mon, 20 Mar 2006 15:10:07 +0000
parents 39ae3dee27b9
children 2157fa46c1e7
rev   line source
Chris@49 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@52 4 Sonic Visualiser
Chris@52 5 An audio file viewer and annotation editor.
Chris@52 6 Centre for Digital Music, Queen Mary, University of London.
Chris@52 7 This file copyright 2006 Chris Cannam.
Chris@0 8
Chris@52 9 This program is free software; you can redistribute it and/or
Chris@52 10 modify it under the terms of the GNU General Public License as
Chris@52 11 published by the Free Software Foundation; either version 2 of the
Chris@52 12 License, or (at your option) any later version. See the file
Chris@52 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@0 16 #include "TransformFactory.h"
Chris@0 17
Chris@0 18 #include "BeatDetectTransform.h"
Chris@0 19 #include "BeatDetectionFunctionTransform.h"
Chris@0 20 #include "FeatureExtractionPluginTransform.h"
Chris@0 21
Chris@0 22 #include "plugin/FeatureExtractionPluginFactory.h"
Chris@0 23
Chris@0 24 #include <iostream>
Chris@0 25
Chris@0 26 TransformFactory *
Chris@0 27 TransformFactory::m_instance = new TransformFactory;
Chris@0 28
Chris@0 29 TransformFactory *
Chris@0 30 TransformFactory::instance()
Chris@0 31 {
Chris@0 32 return m_instance;
Chris@0 33 }
Chris@0 34
Chris@0 35 TransformFactory::~TransformFactory()
Chris@0 36 {
Chris@0 37 }
Chris@0 38
Chris@0 39 TransformFactory::TransformList
Chris@0 40 TransformFactory::getAllTransforms()
Chris@0 41 {
Chris@16 42 if (m_transforms.empty()) populateTransforms();
Chris@16 43
Chris@0 44 TransformList list;
Chris@16 45 for (TransformMap::const_iterator i = m_transforms.begin();
Chris@16 46 i != m_transforms.end(); ++i) {
Chris@16 47 list.push_back(TransformDesc(i->first, i->second));
Chris@16 48 }
Chris@0 49
Chris@16 50 return list;
Chris@16 51 }
Chris@16 52
Chris@16 53 void
Chris@16 54 TransformFactory::populateTransforms()
Chris@16 55 {
Chris@0 56 std::vector<QString> fexplugs =
Chris@0 57 FeatureExtractionPluginFactory::getAllPluginIdentifiers();
Chris@0 58
Chris@47 59 std::map<QString, QString> makers;
Chris@47 60
Chris@0 61 for (size_t i = 0; i < fexplugs.size(); ++i) {
Chris@0 62
Chris@0 63 QString pluginId = fexplugs[i];
Chris@0 64
Chris@0 65 FeatureExtractionPluginFactory *factory =
Chris@0 66 FeatureExtractionPluginFactory::instanceFor(pluginId);
Chris@0 67
Chris@20 68 if (!factory) {
Chris@20 69 std::cerr << "WARNING: TransformFactory::populateTransforms: No feature extraction plugin factory for instance " << pluginId.toLocal8Bit().data() << std::endl;
Chris@20 70 continue;
Chris@20 71 }
Chris@0 72
Chris@20 73 FeatureExtractionPlugin *plugin =
Chris@20 74 factory->instantiatePlugin(pluginId, 48000);
Chris@0 75
Chris@20 76 if (!plugin) {
Chris@20 77 std::cerr << "WARNING: TransformFactory::populateTransforms: Failed to instantiate plugin " << pluginId.toLocal8Bit().data() << std::endl;
Chris@20 78 continue;
Chris@20 79 }
Chris@20 80
Chris@20 81 QString pluginDescription = plugin->getDescription().c_str();
Chris@20 82 FeatureExtractionPlugin::OutputList outputs =
Chris@20 83 plugin->getOutputDescriptors();
Chris@0 84
Chris@20 85 for (size_t j = 0; j < outputs.size(); ++j) {
Chris@0 86
Chris@20 87 QString transformName = QString("%1:%2")
Chris@20 88 .arg(pluginId).arg(outputs[j].name.c_str());
Chris@20 89
Chris@20 90 QString userDescription;
Chris@20 91
Chris@20 92 if (outputs.size() == 1) {
Chris@20 93 userDescription = pluginDescription;
Chris@20 94 } else {
Chris@20 95 userDescription = QString("%1: %2")
Chris@20 96 .arg(pluginDescription)
Chris@20 97 .arg(outputs[j].description.c_str());
Chris@0 98 }
Chris@20 99
Chris@20 100 m_transforms[transformName] = userDescription;
Chris@47 101
Chris@47 102 makers[transformName] = plugin->getMaker().c_str();
Chris@0 103 }
Chris@0 104 }
Chris@47 105
Chris@47 106 // disambiguate plugins with similar descriptions
Chris@47 107
Chris@47 108 std::map<QString, int> descriptions;
Chris@47 109
Chris@47 110 for (TransformMap::iterator i = m_transforms.begin(); i != m_transforms.end();
Chris@47 111 ++i) {
Chris@47 112
Chris@47 113 QString name = i->first, description = i->second;
Chris@47 114
Chris@47 115 ++descriptions[description];
Chris@47 116 ++descriptions[QString("%1 [%2]").arg(description).arg(makers[name])];
Chris@47 117 }
Chris@47 118
Chris@47 119 std::map<QString, int> counts;
Chris@47 120 TransformMap newMap;
Chris@47 121
Chris@47 122 for (TransformMap::iterator i = m_transforms.begin(); i != m_transforms.end();
Chris@47 123 ++i) {
Chris@47 124
Chris@47 125 QString name = i->first, description = i->second;
Chris@47 126
Chris@47 127 if (descriptions[description] > 1) {
Chris@47 128 description = QString("%1 [%2]").arg(description).arg(makers[name]);
Chris@47 129 if (descriptions[description] > 1) {
Chris@47 130 description = QString("%1 <%2>")
Chris@47 131 .arg(description).arg(++counts[description]);
Chris@47 132 }
Chris@47 133 }
Chris@47 134
Chris@47 135 newMap[name] = description;
Chris@47 136 }
Chris@47 137
Chris@47 138 m_transforms = newMap;
Chris@16 139 }
Chris@16 140
Chris@16 141 QString
Chris@16 142 TransformFactory::getTransformDescription(TransformName name)
Chris@16 143 {
Chris@16 144 if (m_transforms.find(name) != m_transforms.end()) {
Chris@16 145 return m_transforms[name];
Chris@16 146 } else return "";
Chris@0 147 }
Chris@0 148
Chris@18 149 QString
Chris@18 150 TransformFactory::getTransformFriendlyName(TransformName name)
Chris@18 151 {
Chris@18 152 QString description = getTransformDescription(name);
Chris@18 153
Chris@18 154 int i = description.indexOf(':');
Chris@18 155 if (i >= 0) {
Chris@18 156 return description.remove(0, i + 2);
Chris@18 157 } else {
Chris@18 158 return description;
Chris@18 159 }
Chris@18 160 }
Chris@18 161
Chris@0 162 Transform *
Chris@0 163 TransformFactory::createTransform(TransformName name, Model *inputModel)
Chris@0 164 {
Chris@0 165 return createTransform(name, inputModel, true);
Chris@0 166 }
Chris@0 167
Chris@0 168 Transform *
Chris@0 169 TransformFactory::createTransform(TransformName name, Model *inputModel,
Chris@0 170 bool start)
Chris@0 171 {
Chris@0 172 Transform *transform = 0;
Chris@0 173
Chris@0 174 if (name == BeatDetectTransform::getName()) {
Chris@0 175 transform = new BeatDetectTransform(inputModel);
Chris@0 176 } else if (name == BeatDetectionFunctionTransform::getName()) {
Chris@0 177 transform = new BeatDetectionFunctionTransform(inputModel);
Chris@0 178 } else {
Chris@0 179 QString id = name.section(':', 0, 2);
Chris@0 180 QString output = name.section(':', 3);
Chris@0 181 if (FeatureExtractionPluginFactory::instanceFor(id)) {
Chris@0 182 transform = new FeatureExtractionPluginTransform(inputModel,
Chris@0 183 id, output);
Chris@0 184 } else {
Chris@0 185 std::cerr << "TransformFactory::createTransform: Unknown transform "
Chris@0 186 << name.toStdString() << std::endl;
Chris@0 187 }
Chris@0 188 }
Chris@0 189
Chris@0 190 if (start && transform) transform->start();
Chris@16 191 transform->setObjectName(name);
Chris@0 192 return transform;
Chris@0 193 }
Chris@0 194
Chris@0 195 Model *
Chris@0 196 TransformFactory::transform(TransformName name, Model *inputModel)
Chris@0 197 {
Chris@0 198 Transform *t = createTransform(name, inputModel, false);
Chris@0 199
Chris@0 200 if (!t) return 0;
Chris@0 201
Chris@0 202 connect(t, SIGNAL(finished()), this, SLOT(transformFinished()));
Chris@0 203
Chris@0 204 t->start();
Chris@0 205 return t->detachOutputModel();
Chris@0 206 }
Chris@0 207
Chris@0 208 void
Chris@0 209 TransformFactory::transformFinished()
Chris@0 210 {
Chris@0 211 QObject *s = sender();
Chris@0 212 Transform *transform = dynamic_cast<Transform *>(s);
Chris@0 213
Chris@0 214 if (!transform) {
Chris@0 215 std::cerr << "WARNING: TransformFactory::transformFinished: sender is not a transform" << std::endl;
Chris@0 216 return;
Chris@0 217 }
Chris@0 218
Chris@0 219 transform->wait(); // unnecessary but reassuring
Chris@0 220 delete transform;
Chris@0 221 }
Chris@0 222