Chris@0
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 Sonic Visualiser
|
Chris@0
|
5 An audio file viewer and annotation editor.
|
Chris@0
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@0
|
7 This file copyright 2006 Chris Cannam.
|
Chris@0
|
8
|
Chris@0
|
9 This program is free software; you can redistribute it and/or
|
Chris@0
|
10 modify it under the terms of the GNU General Public License as
|
Chris@0
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@0
|
12 License, or (at your option) any later version. See the file
|
Chris@0
|
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 "FeatureExtractionPluginTransform.h"
|
Chris@0
|
19 #include "RealTimePluginTransform.h"
|
Chris@0
|
20
|
Chris@0
|
21 #include "plugin/FeatureExtractionPluginFactory.h"
|
Chris@0
|
22 #include "plugin/RealTimePluginFactory.h"
|
Chris@0
|
23 #include "plugin/PluginXml.h"
|
Chris@0
|
24
|
Chris@0
|
25 #include "widgets/PluginParameterDialog.h"
|
Chris@0
|
26
|
Chris@1
|
27 #include "data/model/DenseTimeValueModel.h"
|
Chris@0
|
28
|
Chris@0
|
29 #include <iostream>
|
Chris@0
|
30 #include <set>
|
Chris@0
|
31
|
Chris@0
|
32 #include <QRegExp>
|
Chris@0
|
33
|
Chris@0
|
34 TransformFactory *
|
Chris@0
|
35 TransformFactory::m_instance = new TransformFactory;
|
Chris@0
|
36
|
Chris@0
|
37 TransformFactory *
|
Chris@0
|
38 TransformFactory::getInstance()
|
Chris@0
|
39 {
|
Chris@0
|
40 return m_instance;
|
Chris@0
|
41 }
|
Chris@0
|
42
|
Chris@0
|
43 TransformFactory::~TransformFactory()
|
Chris@0
|
44 {
|
Chris@0
|
45 }
|
Chris@0
|
46
|
Chris@0
|
47 TransformFactory::TransformList
|
Chris@0
|
48 TransformFactory::getAllTransforms()
|
Chris@0
|
49 {
|
Chris@0
|
50 if (m_transforms.empty()) populateTransforms();
|
Chris@0
|
51
|
Chris@0
|
52 TransformList list;
|
Chris@0
|
53 for (TransformDescriptionMap::const_iterator i = m_transforms.begin();
|
Chris@0
|
54 i != m_transforms.end(); ++i) {
|
Chris@0
|
55 list.push_back(i->second);
|
Chris@0
|
56 }
|
Chris@0
|
57
|
Chris@0
|
58 return list;
|
Chris@0
|
59 }
|
Chris@0
|
60
|
Chris@0
|
61 std::vector<QString>
|
Chris@0
|
62 TransformFactory::getAllTransformTypes()
|
Chris@0
|
63 {
|
Chris@0
|
64 if (m_transforms.empty()) populateTransforms();
|
Chris@0
|
65
|
Chris@0
|
66 std::set<QString> types;
|
Chris@0
|
67 for (TransformDescriptionMap::const_iterator i = m_transforms.begin();
|
Chris@0
|
68 i != m_transforms.end(); ++i) {
|
Chris@0
|
69 types.insert(i->second.type);
|
Chris@0
|
70 }
|
Chris@0
|
71
|
Chris@0
|
72 std::vector<QString> rv;
|
Chris@0
|
73 for (std::set<QString>::iterator i = types.begin(); i != types.end(); ++i) {
|
Chris@0
|
74 rv.push_back(*i);
|
Chris@0
|
75 }
|
Chris@0
|
76
|
Chris@0
|
77 return rv;
|
Chris@0
|
78 }
|
Chris@0
|
79
|
Chris@0
|
80 void
|
Chris@0
|
81 TransformFactory::populateTransforms()
|
Chris@0
|
82 {
|
Chris@0
|
83 TransformDescriptionMap transforms;
|
Chris@0
|
84
|
Chris@0
|
85 populateFeatureExtractionPlugins(transforms);
|
Chris@0
|
86 populateRealTimePlugins(transforms);
|
Chris@0
|
87
|
Chris@0
|
88 // disambiguate plugins with similar descriptions
|
Chris@0
|
89
|
Chris@0
|
90 std::map<QString, int> descriptions;
|
Chris@0
|
91
|
Chris@0
|
92 for (TransformDescriptionMap::iterator i = transforms.begin();
|
Chris@0
|
93 i != transforms.end(); ++i) {
|
Chris@0
|
94
|
Chris@0
|
95 TransformDesc desc = i->second;
|
Chris@0
|
96
|
Chris@0
|
97 ++descriptions[desc.description];
|
Chris@0
|
98 ++descriptions[QString("%1 [%2]").arg(desc.description).arg(desc.maker)];
|
Chris@0
|
99 }
|
Chris@0
|
100
|
Chris@0
|
101 std::map<QString, int> counts;
|
Chris@0
|
102 m_transforms.clear();
|
Chris@0
|
103
|
Chris@0
|
104 for (TransformDescriptionMap::iterator i = transforms.begin();
|
Chris@0
|
105 i != transforms.end(); ++i) {
|
Chris@0
|
106
|
Chris@0
|
107 TransformDesc desc = i->second;
|
Chris@0
|
108 QString name = desc.name;
|
Chris@0
|
109 QString description = desc.description;
|
Chris@0
|
110 QString maker = desc.maker;
|
Chris@0
|
111
|
Chris@0
|
112 if (descriptions[description] > 1) {
|
Chris@0
|
113 description = QString("%1 [%2]").arg(description).arg(maker);
|
Chris@0
|
114 if (descriptions[description] > 1) {
|
Chris@0
|
115 description = QString("%1 <%2>")
|
Chris@0
|
116 .arg(description).arg(++counts[description]);
|
Chris@0
|
117 }
|
Chris@0
|
118 }
|
Chris@0
|
119
|
Chris@0
|
120 desc.description = description;
|
Chris@0
|
121 m_transforms[name] = desc;
|
Chris@0
|
122 }
|
Chris@0
|
123 }
|
Chris@0
|
124
|
Chris@0
|
125 void
|
Chris@0
|
126 TransformFactory::populateFeatureExtractionPlugins(TransformDescriptionMap &transforms)
|
Chris@0
|
127 {
|
Chris@0
|
128 std::vector<QString> plugs =
|
Chris@0
|
129 FeatureExtractionPluginFactory::getAllPluginIdentifiers();
|
Chris@0
|
130
|
Chris@0
|
131 for (size_t i = 0; i < plugs.size(); ++i) {
|
Chris@0
|
132
|
Chris@0
|
133 QString pluginId = plugs[i];
|
Chris@0
|
134
|
Chris@0
|
135 FeatureExtractionPluginFactory *factory =
|
Chris@0
|
136 FeatureExtractionPluginFactory::instanceFor(pluginId);
|
Chris@0
|
137
|
Chris@0
|
138 if (!factory) {
|
Chris@0
|
139 std::cerr << "WARNING: TransformFactory::populateTransforms: No feature extraction plugin factory for instance " << pluginId.toLocal8Bit().data() << std::endl;
|
Chris@0
|
140 continue;
|
Chris@0
|
141 }
|
Chris@0
|
142
|
Chris@0
|
143 Vamp::Plugin *plugin =
|
Chris@0
|
144 factory->instantiatePlugin(pluginId, 48000);
|
Chris@0
|
145
|
Chris@0
|
146 if (!plugin) {
|
Chris@0
|
147 std::cerr << "WARNING: TransformFactory::populateTransforms: Failed to instantiate plugin " << pluginId.toLocal8Bit().data() << std::endl;
|
Chris@0
|
148 continue;
|
Chris@0
|
149 }
|
Chris@0
|
150
|
Chris@0
|
151 QString pluginDescription = plugin->getDescription().c_str();
|
Chris@0
|
152 Vamp::Plugin::OutputList outputs =
|
Chris@0
|
153 plugin->getOutputDescriptors();
|
Chris@0
|
154
|
Chris@0
|
155 for (size_t j = 0; j < outputs.size(); ++j) {
|
Chris@0
|
156
|
Chris@0
|
157 QString transformName = QString("%1:%2")
|
Chris@0
|
158 .arg(pluginId).arg(outputs[j].name.c_str());
|
Chris@0
|
159
|
Chris@0
|
160 QString userDescription;
|
Chris@0
|
161 QString friendlyName;
|
Chris@0
|
162 QString units = outputs[j].unit.c_str();
|
Chris@0
|
163
|
Chris@0
|
164 if (outputs.size() == 1) {
|
Chris@0
|
165 userDescription = pluginDescription;
|
Chris@0
|
166 friendlyName = pluginDescription;
|
Chris@0
|
167 } else {
|
Chris@0
|
168 userDescription = QString("%1: %2")
|
Chris@0
|
169 .arg(pluginDescription)
|
Chris@0
|
170 .arg(outputs[j].description.c_str());
|
Chris@0
|
171 friendlyName = outputs[j].description.c_str();
|
Chris@0
|
172 }
|
Chris@0
|
173
|
Chris@0
|
174 bool configurable = (!plugin->getPrograms().empty() ||
|
Chris@0
|
175 !plugin->getParameterDescriptors().empty());
|
Chris@0
|
176
|
Chris@0
|
177 transforms[transformName] =
|
Chris@0
|
178 TransformDesc(tr("Analysis Plugins"),
|
Chris@0
|
179 transformName,
|
Chris@0
|
180 userDescription,
|
Chris@0
|
181 friendlyName,
|
Chris@0
|
182 plugin->getMaker().c_str(),
|
Chris@0
|
183 units,
|
Chris@0
|
184 configurable);
|
Chris@0
|
185 }
|
Chris@0
|
186 }
|
Chris@0
|
187 }
|
Chris@0
|
188
|
Chris@0
|
189 void
|
Chris@0
|
190 TransformFactory::populateRealTimePlugins(TransformDescriptionMap &transforms)
|
Chris@0
|
191 {
|
Chris@0
|
192 std::vector<QString> plugs =
|
Chris@0
|
193 RealTimePluginFactory::getAllPluginIdentifiers();
|
Chris@0
|
194
|
Chris@0
|
195 QRegExp unitRE("[\\[\\(]([A-Za-z0-9/]+)[\\)\\]]$");
|
Chris@0
|
196
|
Chris@0
|
197 for (size_t i = 0; i < plugs.size(); ++i) {
|
Chris@0
|
198
|
Chris@0
|
199 QString pluginId = plugs[i];
|
Chris@0
|
200
|
Chris@0
|
201 RealTimePluginFactory *factory =
|
Chris@0
|
202 RealTimePluginFactory::instanceFor(pluginId);
|
Chris@0
|
203
|
Chris@0
|
204 if (!factory) {
|
Chris@0
|
205 std::cerr << "WARNING: TransformFactory::populateTransforms: No real time plugin factory for instance " << pluginId.toLocal8Bit().data() << std::endl;
|
Chris@0
|
206 continue;
|
Chris@0
|
207 }
|
Chris@0
|
208
|
Chris@0
|
209 const RealTimePluginDescriptor *descriptor =
|
Chris@0
|
210 factory->getPluginDescriptor(pluginId);
|
Chris@0
|
211
|
Chris@0
|
212 if (!descriptor) {
|
Chris@0
|
213 std::cerr << "WARNING: TransformFactory::populateTransforms: Failed to query plugin " << pluginId.toLocal8Bit().data() << std::endl;
|
Chris@0
|
214 continue;
|
Chris@0
|
215 }
|
Chris@0
|
216
|
Chris@0
|
217 if (descriptor->controlOutputPortCount == 0 ||
|
Chris@0
|
218 descriptor->audioInputPortCount == 0) continue;
|
Chris@0
|
219
|
Chris@0
|
220 // std::cout << "TransformFactory::populateRealTimePlugins: plugin " << pluginId.toStdString() << " has " << descriptor->controlOutputPortCount << " output ports" << std::endl;
|
Chris@0
|
221
|
Chris@0
|
222 QString pluginDescription = descriptor->name.c_str();
|
Chris@0
|
223
|
Chris@0
|
224 for (size_t j = 0; j < descriptor->controlOutputPortCount; ++j) {
|
Chris@0
|
225
|
Chris@0
|
226 QString transformName = QString("%1:%2").arg(pluginId).arg(j);
|
Chris@0
|
227 QString userDescription;
|
Chris@0
|
228 QString units;
|
Chris@0
|
229
|
Chris@0
|
230 if (j < descriptor->controlOutputPortNames.size() &&
|
Chris@0
|
231 descriptor->controlOutputPortNames[j] != "") {
|
Chris@0
|
232
|
Chris@0
|
233 QString portName = descriptor->controlOutputPortNames[j].c_str();
|
Chris@0
|
234
|
Chris@0
|
235 userDescription = tr("%1: %2")
|
Chris@0
|
236 .arg(pluginDescription)
|
Chris@0
|
237 .arg(portName);
|
Chris@0
|
238
|
Chris@0
|
239 if (unitRE.indexIn(portName) >= 0) {
|
Chris@0
|
240 units = unitRE.cap(1);
|
Chris@0
|
241 }
|
Chris@0
|
242
|
Chris@0
|
243 } else if (descriptor->controlOutputPortCount > 1) {
|
Chris@0
|
244
|
Chris@0
|
245 userDescription = tr("%1: Output %2")
|
Chris@0
|
246 .arg(pluginDescription)
|
Chris@0
|
247 .arg(j + 1);
|
Chris@0
|
248
|
Chris@0
|
249 } else {
|
Chris@0
|
250
|
Chris@0
|
251 userDescription = pluginDescription;
|
Chris@0
|
252 }
|
Chris@0
|
253
|
Chris@0
|
254
|
Chris@0
|
255 bool configurable = (descriptor->parameterCount > 0);
|
Chris@0
|
256
|
Chris@0
|
257 transforms[transformName] =
|
Chris@0
|
258 TransformDesc(tr("Other Plugins"),
|
Chris@0
|
259 transformName,
|
Chris@0
|
260 userDescription,
|
Chris@0
|
261 userDescription,
|
Chris@0
|
262 descriptor->maker.c_str(),
|
Chris@0
|
263 units,
|
Chris@0
|
264 configurable);
|
Chris@0
|
265 }
|
Chris@0
|
266 }
|
Chris@0
|
267 }
|
Chris@0
|
268
|
Chris@0
|
269 QString
|
Chris@0
|
270 TransformFactory::getTransformDescription(TransformName name)
|
Chris@0
|
271 {
|
Chris@0
|
272 if (m_transforms.find(name) != m_transforms.end()) {
|
Chris@0
|
273 return m_transforms[name].description;
|
Chris@0
|
274 } else return "";
|
Chris@0
|
275 }
|
Chris@0
|
276
|
Chris@0
|
277 QString
|
Chris@0
|
278 TransformFactory::getTransformFriendlyName(TransformName name)
|
Chris@0
|
279 {
|
Chris@0
|
280 if (m_transforms.find(name) != m_transforms.end()) {
|
Chris@0
|
281 return m_transforms[name].friendlyName;
|
Chris@0
|
282 } else return "";
|
Chris@0
|
283 }
|
Chris@0
|
284
|
Chris@0
|
285 QString
|
Chris@0
|
286 TransformFactory::getTransformUnits(TransformName name)
|
Chris@0
|
287 {
|
Chris@0
|
288 if (m_transforms.find(name) != m_transforms.end()) {
|
Chris@0
|
289 return m_transforms[name].units;
|
Chris@0
|
290 } else return "";
|
Chris@0
|
291 }
|
Chris@0
|
292
|
Chris@0
|
293 bool
|
Chris@0
|
294 TransformFactory::isTransformConfigurable(TransformName name)
|
Chris@0
|
295 {
|
Chris@0
|
296 if (m_transforms.find(name) != m_transforms.end()) {
|
Chris@0
|
297 return m_transforms[name].configurable;
|
Chris@0
|
298 } else return false;
|
Chris@0
|
299 }
|
Chris@0
|
300
|
Chris@0
|
301 bool
|
Chris@0
|
302 TransformFactory::getTransformChannelRange(TransformName name,
|
Chris@0
|
303 int &min, int &max)
|
Chris@0
|
304 {
|
Chris@0
|
305 QString id = name.section(':', 0, 2);
|
Chris@0
|
306
|
Chris@0
|
307 if (FeatureExtractionPluginFactory::instanceFor(id)) {
|
Chris@0
|
308
|
Chris@0
|
309 Vamp::Plugin *plugin =
|
Chris@0
|
310 FeatureExtractionPluginFactory::instanceFor(id)->
|
Chris@0
|
311 instantiatePlugin(id, 48000);
|
Chris@0
|
312 if (!plugin) return false;
|
Chris@0
|
313
|
Chris@0
|
314 min = plugin->getMinChannelCount();
|
Chris@0
|
315 max = plugin->getMaxChannelCount();
|
Chris@0
|
316 delete plugin;
|
Chris@0
|
317
|
Chris@0
|
318 return true;
|
Chris@0
|
319
|
Chris@0
|
320 } else if (RealTimePluginFactory::instanceFor(id)) {
|
Chris@0
|
321
|
Chris@0
|
322 const RealTimePluginDescriptor *descriptor =
|
Chris@0
|
323 RealTimePluginFactory::instanceFor(id)->
|
Chris@0
|
324 getPluginDescriptor(id);
|
Chris@0
|
325 if (!descriptor) return false;
|
Chris@0
|
326
|
Chris@0
|
327 min = descriptor->audioInputPortCount;
|
Chris@0
|
328 max = descriptor->audioInputPortCount;
|
Chris@0
|
329
|
Chris@0
|
330 return true;
|
Chris@0
|
331 }
|
Chris@0
|
332
|
Chris@0
|
333 return false;
|
Chris@0
|
334 }
|
Chris@0
|
335
|
Chris@0
|
336 bool
|
Chris@0
|
337 TransformFactory::getChannelRange(TransformName name, Vamp::PluginBase *plugin,
|
Chris@0
|
338 int &minChannels, int &maxChannels)
|
Chris@0
|
339 {
|
Chris@0
|
340 Vamp::Plugin *vp = 0;
|
Chris@0
|
341 if ((vp = dynamic_cast<Vamp::Plugin *>(plugin))) {
|
Chris@0
|
342 minChannels = vp->getMinChannelCount();
|
Chris@0
|
343 maxChannels = vp->getMaxChannelCount();
|
Chris@0
|
344 return true;
|
Chris@0
|
345 } else {
|
Chris@0
|
346 return getTransformChannelRange(name, minChannels, maxChannels);
|
Chris@0
|
347 }
|
Chris@0
|
348 }
|
Chris@0
|
349
|
Chris@0
|
350 bool
|
Chris@0
|
351 TransformFactory::getConfigurationForTransform(TransformName name,
|
Chris@0
|
352 Model *inputModel,
|
Chris@27
|
353 PluginTransform::ExecutionContext &context,
|
Chris@0
|
354 QString &configurationXml)
|
Chris@0
|
355 {
|
Chris@0
|
356 QString id = name.section(':', 0, 2);
|
Chris@0
|
357 QString output = name.section(':', 3);
|
Chris@0
|
358
|
Chris@0
|
359 bool ok = false;
|
Chris@0
|
360 configurationXml = m_lastConfigurations[name];
|
Chris@0
|
361
|
Chris@0
|
362 // std::cerr << "last configuration: " << configurationXml.toStdString() << std::endl;
|
Chris@0
|
363
|
Chris@0
|
364 Vamp::PluginBase *plugin = 0;
|
Chris@0
|
365
|
Chris@10
|
366 bool frequency = false;
|
Chris@10
|
367
|
Chris@0
|
368 if (FeatureExtractionPluginFactory::instanceFor(id)) {
|
Chris@0
|
369
|
Chris@10
|
370 Vamp::Plugin *vp =
|
Chris@10
|
371 FeatureExtractionPluginFactory::instanceFor(id)->instantiatePlugin
|
Chris@0
|
372 (id, inputModel->getSampleRate());
|
Chris@10
|
373 if (vp) {
|
Chris@10
|
374 plugin = vp;
|
Chris@10
|
375 frequency = (vp->getInputDomain() == Vamp::Plugin::FrequencyDomain);
|
Chris@10
|
376 }
|
Chris@0
|
377
|
Chris@0
|
378 } else if (RealTimePluginFactory::instanceFor(id)) {
|
Chris@0
|
379
|
Chris@0
|
380 plugin = RealTimePluginFactory::instanceFor(id)->instantiatePlugin
|
Chris@0
|
381 (id, 0, 0, inputModel->getSampleRate(), 1024, 1);
|
Chris@0
|
382 }
|
Chris@0
|
383
|
Chris@0
|
384 if (plugin) {
|
Chris@27
|
385
|
Chris@27
|
386 context = PluginTransform::ExecutionContext(context.channel, plugin);
|
Chris@27
|
387
|
Chris@0
|
388 if (configurationXml != "") {
|
Chris@0
|
389 PluginXml(plugin).setParametersFromXml(configurationXml);
|
Chris@0
|
390 }
|
Chris@0
|
391
|
Chris@0
|
392 int sourceChannels = 1;
|
Chris@0
|
393 if (dynamic_cast<DenseTimeValueModel *>(inputModel)) {
|
Chris@0
|
394 sourceChannels = dynamic_cast<DenseTimeValueModel *>(inputModel)
|
Chris@0
|
395 ->getChannelCount();
|
Chris@0
|
396 }
|
Chris@0
|
397
|
Chris@0
|
398 int minChannels = 1, maxChannels = sourceChannels;
|
Chris@0
|
399 getChannelRange(name, plugin, minChannels, maxChannels);
|
Chris@0
|
400
|
Chris@0
|
401 int targetChannels = sourceChannels;
|
Chris@0
|
402 if (sourceChannels < minChannels) targetChannels = minChannels;
|
Chris@0
|
403 if (sourceChannels > maxChannels) targetChannels = maxChannels;
|
Chris@0
|
404
|
Chris@27
|
405 int defaultChannel = context.channel;
|
Chris@0
|
406
|
Chris@0
|
407 PluginParameterDialog *dialog = new PluginParameterDialog(plugin,
|
Chris@0
|
408 sourceChannels,
|
Chris@0
|
409 targetChannels,
|
Chris@0
|
410 defaultChannel,
|
Chris@10
|
411 output,
|
Chris@10
|
412 true,
|
Chris@10
|
413 frequency);
|
Chris@0
|
414 if (dialog->exec() == QDialog::Accepted) {
|
Chris@0
|
415 ok = true;
|
Chris@0
|
416 }
|
Chris@0
|
417 configurationXml = PluginXml(plugin).toXmlString();
|
Chris@27
|
418 context.channel = dialog->getChannel();
|
Chris@26
|
419
|
Chris@27
|
420 dialog->getProcessingParameters(context.stepSize,
|
Chris@27
|
421 context.blockSize,
|
Chris@27
|
422 context.windowType);
|
Chris@27
|
423
|
Chris@27
|
424 context.makeConsistentWithPlugin(plugin);
|
Chris@26
|
425
|
Chris@0
|
426 delete dialog;
|
Chris@0
|
427 delete plugin;
|
Chris@0
|
428 }
|
Chris@0
|
429
|
Chris@0
|
430 if (ok) m_lastConfigurations[name] = configurationXml;
|
Chris@0
|
431
|
Chris@0
|
432 return ok;
|
Chris@0
|
433 }
|
Chris@0
|
434
|
Chris@0
|
435 Transform *
|
Chris@0
|
436 TransformFactory::createTransform(TransformName name, Model *inputModel,
|
Chris@27
|
437 const PluginTransform::ExecutionContext &context,
|
Chris@27
|
438 QString configurationXml, bool start)
|
Chris@0
|
439 {
|
Chris@0
|
440 Transform *transform = 0;
|
Chris@0
|
441
|
Chris@0
|
442 QString id = name.section(':', 0, 2);
|
Chris@0
|
443 QString output = name.section(':', 3);
|
Chris@0
|
444
|
Chris@0
|
445 if (FeatureExtractionPluginFactory::instanceFor(id)) {
|
Chris@0
|
446 transform = new FeatureExtractionPluginTransform(inputModel,
|
Chris@0
|
447 id,
|
Chris@27
|
448 context,
|
Chris@0
|
449 configurationXml,
|
Chris@0
|
450 output);
|
Chris@0
|
451 } else if (RealTimePluginFactory::instanceFor(id)) {
|
Chris@0
|
452 transform = new RealTimePluginTransform(inputModel,
|
Chris@0
|
453 id,
|
Chris@27
|
454 context,
|
Chris@0
|
455 configurationXml,
|
Chris@0
|
456 getTransformUnits(name),
|
Chris@0
|
457 output.toInt());
|
Chris@0
|
458 } else {
|
Chris@0
|
459 std::cerr << "TransformFactory::createTransform: Unknown transform \""
|
Chris@0
|
460 << name.toStdString() << "\"" << std::endl;
|
Chris@0
|
461 return transform;
|
Chris@0
|
462 }
|
Chris@0
|
463
|
Chris@0
|
464 if (start && transform) transform->start();
|
Chris@0
|
465 transform->setObjectName(name);
|
Chris@0
|
466 return transform;
|
Chris@0
|
467 }
|
Chris@0
|
468
|
Chris@0
|
469 Model *
|
Chris@0
|
470 TransformFactory::transform(TransformName name, Model *inputModel,
|
Chris@27
|
471 const PluginTransform::ExecutionContext &context,
|
Chris@27
|
472 QString configurationXml)
|
Chris@0
|
473 {
|
Chris@27
|
474 Transform *t = createTransform(name, inputModel, context,
|
Chris@0
|
475 configurationXml, false);
|
Chris@0
|
476
|
Chris@0
|
477 if (!t) return 0;
|
Chris@0
|
478
|
Chris@0
|
479 connect(t, SIGNAL(finished()), this, SLOT(transformFinished()));
|
Chris@0
|
480
|
Chris@0
|
481 t->start();
|
Chris@0
|
482 return t->detachOutputModel();
|
Chris@0
|
483 }
|
Chris@0
|
484
|
Chris@0
|
485 void
|
Chris@0
|
486 TransformFactory::transformFinished()
|
Chris@0
|
487 {
|
Chris@0
|
488 QObject *s = sender();
|
Chris@0
|
489 Transform *transform = dynamic_cast<Transform *>(s);
|
Chris@0
|
490
|
Chris@0
|
491 if (!transform) {
|
Chris@0
|
492 std::cerr << "WARNING: TransformFactory::transformFinished: sender is not a transform" << std::endl;
|
Chris@0
|
493 return;
|
Chris@0
|
494 }
|
Chris@0
|
495
|
Chris@0
|
496 transform->wait(); // unnecessary but reassuring
|
Chris@0
|
497 delete transform;
|
Chris@0
|
498 }
|
Chris@0
|
499
|