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
|