annotate transform/TransformFactory.cpp @ 33:51e158b505da

* Rearrange spectrogram cacheing so that gain, normalization, instantaneous frequency calculations etc can be done from the cached data (increasing the size of the cache, but also the usability).
author Chris Cannam
date Thu, 23 Feb 2006 18:01:31 +0000
parents 742e6882e187
children bac8b14ab355
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@0 4 A waveform viewer and audio annotation editor.
Chris@2 5 Chris Cannam, Queen Mary University of London, 2005-2006
Chris@0 6
Chris@0 7 This is experimental software. Not for distribution.
Chris@0 8 */
Chris@0 9
Chris@0 10 #include "TransformFactory.h"
Chris@0 11
Chris@0 12 #include "BeatDetectTransform.h"
Chris@0 13 #include "BeatDetectionFunctionTransform.h"
Chris@0 14 #include "FeatureExtractionPluginTransform.h"
Chris@0 15
Chris@0 16 #include "plugin/FeatureExtractionPluginFactory.h"
Chris@0 17
Chris@0 18 #include <iostream>
Chris@0 19
Chris@0 20 TransformFactory *
Chris@0 21 TransformFactory::m_instance = new TransformFactory;
Chris@0 22
Chris@0 23 TransformFactory *
Chris@0 24 TransformFactory::instance()
Chris@0 25 {
Chris@0 26 return m_instance;
Chris@0 27 }
Chris@0 28
Chris@0 29 TransformFactory::~TransformFactory()
Chris@0 30 {
Chris@0 31 }
Chris@0 32
Chris@0 33 TransformFactory::TransformList
Chris@0 34 TransformFactory::getAllTransforms()
Chris@0 35 {
Chris@16 36 if (m_transforms.empty()) populateTransforms();
Chris@16 37
Chris@0 38 TransformList list;
Chris@16 39 for (TransformMap::const_iterator i = m_transforms.begin();
Chris@16 40 i != m_transforms.end(); ++i) {
Chris@16 41 list.push_back(TransformDesc(i->first, i->second));
Chris@16 42 }
Chris@0 43
Chris@16 44 return list;
Chris@16 45 }
Chris@16 46
Chris@16 47 void
Chris@16 48 TransformFactory::populateTransforms()
Chris@16 49 {
Chris@0 50 //!!!
Chris@0 51 std::vector<QString> fexplugs =
Chris@0 52 FeatureExtractionPluginFactory::getAllPluginIdentifiers();
Chris@0 53
Chris@0 54 for (size_t i = 0; i < fexplugs.size(); ++i) {
Chris@0 55
Chris@0 56 QString pluginId = fexplugs[i];
Chris@0 57
Chris@0 58 FeatureExtractionPluginFactory *factory =
Chris@0 59 FeatureExtractionPluginFactory::instanceFor(pluginId);
Chris@0 60
Chris@20 61 if (!factory) {
Chris@20 62 std::cerr << "WARNING: TransformFactory::populateTransforms: No feature extraction plugin factory for instance " << pluginId.toLocal8Bit().data() << std::endl;
Chris@20 63 continue;
Chris@20 64 }
Chris@0 65
Chris@20 66 //!!! well, really we want to be able to query this without having to instantiate
Chris@0 67
Chris@20 68 FeatureExtractionPlugin *plugin =
Chris@20 69 factory->instantiatePlugin(pluginId, 48000);
Chris@0 70
Chris@20 71 if (!plugin) {
Chris@20 72 std::cerr << "WARNING: TransformFactory::populateTransforms: Failed to instantiate plugin " << pluginId.toLocal8Bit().data() << std::endl;
Chris@20 73 continue;
Chris@20 74 }
Chris@20 75
Chris@20 76 QString pluginDescription = plugin->getDescription().c_str();
Chris@20 77 FeatureExtractionPlugin::OutputList outputs =
Chris@20 78 plugin->getOutputDescriptors();
Chris@0 79
Chris@20 80 for (size_t j = 0; j < outputs.size(); ++j) {
Chris@0 81
Chris@20 82 QString transformName = QString("%1:%2")
Chris@20 83 .arg(pluginId).arg(outputs[j].name.c_str());
Chris@20 84
Chris@20 85 QString userDescription;
Chris@20 86
Chris@20 87 if (outputs.size() == 1) {
Chris@20 88 userDescription = pluginDescription;
Chris@20 89 } else {
Chris@20 90 userDescription = QString("%1: %2")
Chris@20 91 .arg(pluginDescription)
Chris@20 92 .arg(outputs[j].description.c_str());
Chris@0 93 }
Chris@20 94
Chris@20 95 m_transforms[transformName] = userDescription;
Chris@0 96 }
Chris@0 97 }
Chris@16 98 }
Chris@16 99
Chris@16 100 QString
Chris@16 101 TransformFactory::getTransformDescription(TransformName name)
Chris@16 102 {
Chris@16 103 if (m_transforms.find(name) != m_transforms.end()) {
Chris@16 104 return m_transforms[name];
Chris@16 105 } else return "";
Chris@0 106 }
Chris@0 107
Chris@18 108 QString
Chris@18 109 TransformFactory::getTransformFriendlyName(TransformName name)
Chris@18 110 {
Chris@18 111 QString description = getTransformDescription(name);
Chris@18 112
Chris@18 113 int i = description.indexOf(':');
Chris@18 114 if (i >= 0) {
Chris@18 115 return description.remove(0, i + 2);
Chris@18 116 } else {
Chris@18 117 return description;
Chris@18 118 }
Chris@18 119 }
Chris@18 120
Chris@0 121 Transform *
Chris@0 122 TransformFactory::createTransform(TransformName name, Model *inputModel)
Chris@0 123 {
Chris@0 124 return createTransform(name, inputModel, true);
Chris@0 125 }
Chris@0 126
Chris@0 127 Transform *
Chris@0 128 TransformFactory::createTransform(TransformName name, Model *inputModel,
Chris@0 129 bool start)
Chris@0 130 {
Chris@0 131 Transform *transform = 0;
Chris@0 132
Chris@0 133 if (name == BeatDetectTransform::getName()) {
Chris@0 134 transform = new BeatDetectTransform(inputModel);
Chris@0 135 } else if (name == BeatDetectionFunctionTransform::getName()) {
Chris@0 136 transform = new BeatDetectionFunctionTransform(inputModel);
Chris@0 137 } else {
Chris@0 138 QString id = name.section(':', 0, 2);
Chris@0 139 QString output = name.section(':', 3);
Chris@0 140 if (FeatureExtractionPluginFactory::instanceFor(id)) {
Chris@0 141 transform = new FeatureExtractionPluginTransform(inputModel,
Chris@0 142 id, output);
Chris@0 143 } else {
Chris@0 144 std::cerr << "TransformFactory::createTransform: Unknown transform "
Chris@0 145 << name.toStdString() << std::endl;
Chris@0 146 }
Chris@0 147 }
Chris@0 148
Chris@0 149 if (start && transform) transform->start();
Chris@16 150 transform->setObjectName(name);
Chris@0 151 return transform;
Chris@0 152 }
Chris@0 153
Chris@0 154 Model *
Chris@0 155 TransformFactory::transform(TransformName name, Model *inputModel)
Chris@0 156 {
Chris@0 157 Transform *t = createTransform(name, inputModel, false);
Chris@0 158
Chris@0 159 if (!t) return 0;
Chris@0 160
Chris@0 161 connect(t, SIGNAL(finished()), this, SLOT(transformFinished()));
Chris@0 162
Chris@0 163 t->start();
Chris@0 164 return t->detachOutputModel();
Chris@0 165 }
Chris@0 166
Chris@0 167 void
Chris@0 168 TransformFactory::transformFinished()
Chris@0 169 {
Chris@0 170 QObject *s = sender();
Chris@0 171 Transform *transform = dynamic_cast<Transform *>(s);
Chris@0 172
Chris@0 173 if (!transform) {
Chris@0 174 std::cerr << "WARNING: TransformFactory::transformFinished: sender is not a transform" << std::endl;
Chris@0 175 return;
Chris@0 176 }
Chris@0 177
Chris@0 178 transform->wait(); // unnecessary but reassuring
Chris@0 179 delete transform;
Chris@0 180 }
Chris@0 181