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@0
|
61 if (factory) {
|
Chris@0
|
62 //!!! well, really we want to be able to query this without having to instantiate
|
Chris@0
|
63
|
Chris@0
|
64 FeatureExtractionPlugin *plugin =
|
Chris@0
|
65 factory->instantiatePlugin(pluginId, 48000);
|
Chris@0
|
66
|
Chris@0
|
67 QString pluginDescription = plugin->getDescription().c_str();
|
Chris@0
|
68
|
Chris@0
|
69 if (plugin) {
|
Chris@0
|
70
|
Chris@0
|
71 FeatureExtractionPlugin::OutputList outputs =
|
Chris@0
|
72 plugin->getOutputDescriptors();
|
Chris@0
|
73
|
Chris@0
|
74 if (outputs.size() == 1) {
|
Chris@16
|
75 m_transforms[QString("%1:%2")
|
Chris@16
|
76 .arg(pluginId)
|
Chris@16
|
77 .arg(outputs[0].name.c_str())]
|
Chris@16
|
78 = pluginDescription;
|
Chris@0
|
79 } else {
|
Chris@0
|
80 for (size_t j = 0; j < outputs.size(); ++j) {
|
Chris@16
|
81 m_transforms[QString("%1:%2")
|
Chris@16
|
82 .arg(pluginId)
|
Chris@16
|
83 .arg(outputs[j].name.c_str())]
|
Chris@16
|
84 = QString("%1: %2")
|
Chris@16
|
85 .arg(pluginDescription)
|
Chris@16
|
86 .arg(outputs[j].description.c_str());
|
Chris@0
|
87 }
|
Chris@0
|
88 }
|
Chris@0
|
89 }
|
Chris@0
|
90 }
|
Chris@0
|
91 }
|
Chris@16
|
92 }
|
Chris@16
|
93
|
Chris@16
|
94 QString
|
Chris@16
|
95 TransformFactory::getTransformDescription(TransformName name)
|
Chris@16
|
96 {
|
Chris@16
|
97 if (m_transforms.find(name) != m_transforms.end()) {
|
Chris@16
|
98 return m_transforms[name];
|
Chris@16
|
99 } else return "";
|
Chris@0
|
100 }
|
Chris@0
|
101
|
Chris@18
|
102 QString
|
Chris@18
|
103 TransformFactory::getTransformFriendlyName(TransformName name)
|
Chris@18
|
104 {
|
Chris@18
|
105 QString description = getTransformDescription(name);
|
Chris@18
|
106
|
Chris@18
|
107 int i = description.indexOf(':');
|
Chris@18
|
108 if (i >= 0) {
|
Chris@18
|
109 return description.remove(0, i + 2);
|
Chris@18
|
110 } else {
|
Chris@18
|
111 return description;
|
Chris@18
|
112 }
|
Chris@18
|
113 }
|
Chris@18
|
114
|
Chris@0
|
115 Transform *
|
Chris@0
|
116 TransformFactory::createTransform(TransformName name, Model *inputModel)
|
Chris@0
|
117 {
|
Chris@0
|
118 return createTransform(name, inputModel, true);
|
Chris@0
|
119 }
|
Chris@0
|
120
|
Chris@0
|
121 Transform *
|
Chris@0
|
122 TransformFactory::createTransform(TransformName name, Model *inputModel,
|
Chris@0
|
123 bool start)
|
Chris@0
|
124 {
|
Chris@0
|
125 Transform *transform = 0;
|
Chris@0
|
126
|
Chris@0
|
127 if (name == BeatDetectTransform::getName()) {
|
Chris@0
|
128 transform = new BeatDetectTransform(inputModel);
|
Chris@0
|
129 } else if (name == BeatDetectionFunctionTransform::getName()) {
|
Chris@0
|
130 transform = new BeatDetectionFunctionTransform(inputModel);
|
Chris@0
|
131 } else {
|
Chris@0
|
132 QString id = name.section(':', 0, 2);
|
Chris@0
|
133 QString output = name.section(':', 3);
|
Chris@0
|
134 if (FeatureExtractionPluginFactory::instanceFor(id)) {
|
Chris@0
|
135 transform = new FeatureExtractionPluginTransform(inputModel,
|
Chris@0
|
136 id, output);
|
Chris@0
|
137 } else {
|
Chris@0
|
138 std::cerr << "TransformFactory::createTransform: Unknown transform "
|
Chris@0
|
139 << name.toStdString() << std::endl;
|
Chris@0
|
140 }
|
Chris@0
|
141 }
|
Chris@0
|
142
|
Chris@0
|
143 if (start && transform) transform->start();
|
Chris@16
|
144 transform->setObjectName(name);
|
Chris@0
|
145 return transform;
|
Chris@0
|
146 }
|
Chris@0
|
147
|
Chris@0
|
148 Model *
|
Chris@0
|
149 TransformFactory::transform(TransformName name, Model *inputModel)
|
Chris@0
|
150 {
|
Chris@0
|
151 Transform *t = createTransform(name, inputModel, false);
|
Chris@0
|
152
|
Chris@0
|
153 if (!t) return 0;
|
Chris@0
|
154
|
Chris@0
|
155 connect(t, SIGNAL(finished()), this, SLOT(transformFinished()));
|
Chris@0
|
156
|
Chris@0
|
157 t->start();
|
Chris@0
|
158 return t->detachOutputModel();
|
Chris@0
|
159 }
|
Chris@0
|
160
|
Chris@0
|
161 void
|
Chris@0
|
162 TransformFactory::transformFinished()
|
Chris@0
|
163 {
|
Chris@0
|
164 QObject *s = sender();
|
Chris@0
|
165 Transform *transform = dynamic_cast<Transform *>(s);
|
Chris@0
|
166
|
Chris@0
|
167 if (!transform) {
|
Chris@0
|
168 std::cerr << "WARNING: TransformFactory::transformFinished: sender is not a transform" << std::endl;
|
Chris@0
|
169 return;
|
Chris@0
|
170 }
|
Chris@0
|
171
|
Chris@0
|
172 transform->wait(); // unnecessary but reassuring
|
Chris@0
|
173 delete transform;
|
Chris@0
|
174 }
|
Chris@0
|
175
|