Chris@320
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@320
|
2
|
Chris@320
|
3 /*
|
Chris@320
|
4 Sonic Visualiser
|
Chris@320
|
5 An audio file viewer and annotation editor.
|
Chris@320
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@328
|
7 This file copyright 2006-2007 Chris Cannam and QMUL.
|
Chris@320
|
8
|
Chris@320
|
9 This program is free software; you can redistribute it and/or
|
Chris@320
|
10 modify it under the terms of the GNU General Public License as
|
Chris@320
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@320
|
12 License, or (at your option) any later version. See the file
|
Chris@320
|
13 COPYING included with this distribution for more information.
|
Chris@320
|
14 */
|
Chris@320
|
15
|
Chris@320
|
16 #include "Transform.h"
|
Chris@320
|
17
|
Chris@328
|
18 #include "plugin/PluginIdentifier.h"
|
Chris@328
|
19
|
Chris@332
|
20 #include "plugin/FeatureExtractionPluginFactory.h"
|
Chris@332
|
21
|
Chris@350
|
22 #include <QXmlAttributes>
|
Chris@350
|
23
|
Chris@350
|
24 #include <QDomDocument>
|
Chris@350
|
25 #include <QDomElement>
|
Chris@350
|
26 #include <QDomNamedNodeMap>
|
Chris@350
|
27 #include <QDomAttr>
|
Chris@350
|
28
|
Chris@350
|
29 #include <QTextStream>
|
Chris@350
|
30
|
Chris@350
|
31 #include <iostream>
|
Chris@350
|
32
|
Chris@328
|
33 Transform::Transform() :
|
Chris@328
|
34 m_stepSize(0),
|
Chris@328
|
35 m_blockSize(0),
|
Chris@328
|
36 m_windowType(HanningWindow),
|
Chris@328
|
37 m_sampleRate(0)
|
Chris@320
|
38 {
|
Chris@320
|
39 }
|
Chris@320
|
40
|
Chris@350
|
41 Transform::Transform(QString xml) :
|
Chris@350
|
42 m_stepSize(0),
|
Chris@350
|
43 m_blockSize(0),
|
Chris@350
|
44 m_windowType(HanningWindow),
|
Chris@350
|
45 m_sampleRate(0)
|
Chris@350
|
46 {
|
Chris@350
|
47 QDomDocument doc;
|
Chris@350
|
48
|
Chris@350
|
49 QString error;
|
Chris@350
|
50 int errorLine;
|
Chris@350
|
51 int errorColumn;
|
Chris@350
|
52
|
Chris@350
|
53 if (!doc.setContent(xml, false, &error, &errorLine, &errorColumn)) {
|
Chris@350
|
54 std::cerr << "Transform::Transform: Error in parsing XML: "
|
Chris@350
|
55 << error.toStdString() << " at line " << errorLine
|
Chris@350
|
56 << ", column " << errorColumn << std::endl;
|
Chris@350
|
57 std::cerr << "Input follows:" << std::endl;
|
Chris@350
|
58 std::cerr << xml.toStdString() << std::endl;
|
Chris@350
|
59 std::cerr << "Input ends." << std::endl;
|
Chris@350
|
60 return;
|
Chris@350
|
61 }
|
Chris@350
|
62
|
Chris@350
|
63 QDomElement transformElt = doc.firstChildElement("transform");
|
Chris@350
|
64 QDomNamedNodeMap attrNodes = transformElt.attributes();
|
Chris@350
|
65 QXmlAttributes attrs;
|
Chris@350
|
66
|
Chris@350
|
67 for (unsigned int i = 0; i < attrNodes.length(); ++i) {
|
Chris@350
|
68 QDomAttr attr = attrNodes.item(i).toAttr();
|
Chris@350
|
69 if (!attr.isNull()) attrs.append(attr.name(), "", "", attr.value());
|
Chris@350
|
70 }
|
Chris@350
|
71
|
Chris@350
|
72 setFromXmlAttributes(attrs);
|
Chris@350
|
73
|
Chris@350
|
74 for (QDomElement paramElt = transformElt.firstChildElement("parameter");
|
Chris@350
|
75 !paramElt.isNull();
|
Chris@350
|
76 paramElt = paramElt.nextSiblingElement("parameter")) {
|
Chris@350
|
77
|
Chris@350
|
78 QDomNamedNodeMap paramAttrs = paramElt.attributes();
|
Chris@350
|
79
|
Chris@350
|
80 QDomAttr nameAttr = paramAttrs.namedItem("name").toAttr();
|
Chris@350
|
81 if (nameAttr.isNull() || nameAttr.value() == "") continue;
|
Chris@350
|
82
|
Chris@350
|
83 QDomAttr valueAttr = paramAttrs.namedItem("value").toAttr();
|
Chris@350
|
84 if (valueAttr.isNull() || valueAttr.value() == "") continue;
|
Chris@350
|
85
|
Chris@350
|
86 setParameter(nameAttr.value(), valueAttr.value().toFloat());
|
Chris@350
|
87 }
|
Chris@350
|
88
|
Chris@350
|
89 for (QDomElement configElt = transformElt.firstChildElement("configuration");
|
Chris@350
|
90 !configElt.isNull();
|
Chris@350
|
91 configElt = configElt.nextSiblingElement("configuration")) {
|
Chris@350
|
92
|
Chris@350
|
93 QDomNamedNodeMap configAttrs = configElt.attributes();
|
Chris@350
|
94
|
Chris@350
|
95 QDomAttr nameAttr = configAttrs.namedItem("name").toAttr();
|
Chris@350
|
96 if (nameAttr.isNull() || nameAttr.value() == "") continue;
|
Chris@350
|
97
|
Chris@350
|
98 QDomAttr valueAttr = configAttrs.namedItem("value").toAttr();
|
Chris@350
|
99 if (valueAttr.isNull() || valueAttr.value() == "") continue;
|
Chris@350
|
100
|
Chris@350
|
101 setConfigurationValue(nameAttr.value(), valueAttr.value());
|
Chris@350
|
102 }
|
Chris@350
|
103 }
|
Chris@350
|
104
|
Chris@320
|
105 Transform::~Transform()
|
Chris@320
|
106 {
|
Chris@320
|
107 }
|
Chris@320
|
108
|
Chris@350
|
109 bool
|
Chris@350
|
110 Transform::operator==(const Transform &t)
|
Chris@350
|
111 {
|
Chris@350
|
112 return
|
Chris@350
|
113 m_id == t.m_id &&
|
Chris@350
|
114 m_parameters == t.m_parameters &&
|
Chris@350
|
115 m_configuration == t.m_configuration &&
|
Chris@350
|
116 m_program == t.m_program &&
|
Chris@350
|
117 m_stepSize == t.m_stepSize &&
|
Chris@350
|
118 m_blockSize == t.m_blockSize &&
|
Chris@350
|
119 m_windowType == t.m_windowType &&
|
Chris@350
|
120 m_startTime == t.m_startTime &&
|
Chris@350
|
121 m_duration == t.m_duration &&
|
Chris@350
|
122 m_sampleRate == t.m_sampleRate;
|
Chris@350
|
123 }
|
Chris@350
|
124
|
Chris@350
|
125 void
|
Chris@350
|
126 Transform::setIdentifier(TransformId id)
|
Chris@350
|
127 {
|
Chris@350
|
128 m_id = id;
|
Chris@350
|
129 }
|
Chris@350
|
130
|
Chris@350
|
131 TransformId
|
Chris@350
|
132 Transform::getIdentifier() const
|
Chris@350
|
133 {
|
Chris@350
|
134 return m_id;
|
Chris@350
|
135 }
|
Chris@350
|
136
|
Chris@328
|
137 QString
|
Chris@328
|
138 Transform::createIdentifier(QString type, QString soName, QString label,
|
Chris@328
|
139 QString output)
|
Chris@328
|
140 {
|
Chris@328
|
141 QString pluginId = PluginIdentifier::createIdentifier(type, soName, label);
|
Chris@328
|
142 return pluginId + ":" + output;
|
Chris@328
|
143 }
|
Chris@328
|
144
|
Chris@328
|
145 void
|
Chris@328
|
146 Transform::parseIdentifier(QString identifier,
|
Chris@328
|
147 QString &type, QString &soName,
|
Chris@328
|
148 QString &label, QString &output)
|
Chris@328
|
149 {
|
Chris@328
|
150 output = identifier.section(':', 3);
|
Chris@328
|
151 PluginIdentifier::parseIdentifier(identifier.section(':', 0, 2),
|
Chris@328
|
152 type, soName, label);
|
Chris@328
|
153 }
|
Chris@328
|
154
|
Chris@328
|
155 Transform::Type
|
Chris@328
|
156 Transform::getType() const
|
Chris@328
|
157 {
|
Chris@332
|
158 if (FeatureExtractionPluginFactory::instanceFor(getPluginIdentifier())) {
|
Chris@332
|
159 return FeatureExtraction;
|
Chris@332
|
160 } else {
|
Chris@332
|
161 // We don't have an unknown/invalid return value, so always
|
Chris@332
|
162 // return this
|
Chris@332
|
163 return RealTimeEffect;
|
Chris@332
|
164 }
|
Chris@328
|
165 }
|
Chris@328
|
166
|
Chris@328
|
167 QString
|
Chris@328
|
168 Transform::getPluginIdentifier() const
|
Chris@328
|
169 {
|
Chris@328
|
170 return m_id.section(':', 0, 2);
|
Chris@328
|
171 }
|
Chris@328
|
172
|
Chris@328
|
173 QString
|
Chris@328
|
174 Transform::getOutput() const
|
Chris@328
|
175 {
|
Chris@328
|
176 return m_id.section(':', 3);
|
Chris@328
|
177 }
|
Chris@328
|
178
|
Chris@350
|
179 const Transform::ParameterMap &
|
Chris@350
|
180 Transform::getParameters() const
|
Chris@350
|
181 {
|
Chris@350
|
182 return m_parameters;
|
Chris@350
|
183 }
|
Chris@350
|
184
|
Chris@328
|
185 void
|
Chris@350
|
186 Transform::setParameters(const ParameterMap &pm)
|
Chris@328
|
187 {
|
Chris@350
|
188 m_parameters = pm;
|
Chris@350
|
189 }
|
Chris@350
|
190
|
Chris@350
|
191 void
|
Chris@350
|
192 Transform::setParameter(QString name, float value)
|
Chris@350
|
193 {
|
Chris@350
|
194 std::cerr << "Transform::setParameter(" << name.toStdString()
|
Chris@350
|
195 << ") -> " << value << std::endl;
|
Chris@350
|
196 m_parameters[name] = value;
|
Chris@350
|
197 }
|
Chris@350
|
198
|
Chris@350
|
199 const Transform::ConfigurationMap &
|
Chris@350
|
200 Transform::getConfiguration() const
|
Chris@350
|
201 {
|
Chris@350
|
202 return m_configuration;
|
Chris@350
|
203 }
|
Chris@350
|
204
|
Chris@350
|
205 void
|
Chris@350
|
206 Transform::setConfiguration(const ConfigurationMap &cm)
|
Chris@350
|
207 {
|
Chris@350
|
208 m_configuration = cm;
|
Chris@350
|
209 }
|
Chris@350
|
210
|
Chris@350
|
211 void
|
Chris@350
|
212 Transform::setConfigurationValue(QString name, QString value)
|
Chris@350
|
213 {
|
Chris@350
|
214 std::cerr << "Transform::setConfigurationValue(" << name.toStdString()
|
Chris@350
|
215 << ") -> " << value.toStdString() << std::endl;
|
Chris@350
|
216 m_configuration[name] = value;
|
Chris@350
|
217 }
|
Chris@350
|
218
|
Chris@350
|
219 QString
|
Chris@350
|
220 Transform::getProgram() const
|
Chris@350
|
221 {
|
Chris@350
|
222 return m_program;
|
Chris@350
|
223 }
|
Chris@350
|
224
|
Chris@350
|
225 void
|
Chris@350
|
226 Transform::setProgram(QString program)
|
Chris@350
|
227 {
|
Chris@350
|
228 m_program = program;
|
Chris@350
|
229 }
|
Chris@350
|
230
|
Chris@328
|
231
|
Chris@350
|
232 size_t
|
Chris@350
|
233 Transform::getStepSize() const
|
Chris@350
|
234 {
|
Chris@350
|
235 return m_stepSize;
|
Chris@328
|
236 }
|
Chris@350
|
237
|
Chris@350
|
238 void
|
Chris@350
|
239 Transform::setStepSize(size_t s)
|
Chris@350
|
240 {
|
Chris@350
|
241 m_stepSize = s;
|
Chris@350
|
242 }
|
Chris@350
|
243
|
Chris@350
|
244 size_t
|
Chris@350
|
245 Transform::getBlockSize() const
|
Chris@350
|
246 {
|
Chris@350
|
247 return m_blockSize;
|
Chris@350
|
248 }
|
Chris@350
|
249
|
Chris@350
|
250 void
|
Chris@350
|
251 Transform::setBlockSize(size_t s)
|
Chris@350
|
252 {
|
Chris@350
|
253 m_blockSize = s;
|
Chris@350
|
254 }
|
Chris@350
|
255
|
Chris@350
|
256 WindowType
|
Chris@350
|
257 Transform::getWindowType() const
|
Chris@350
|
258 {
|
Chris@350
|
259 return m_windowType;
|
Chris@350
|
260 }
|
Chris@350
|
261
|
Chris@350
|
262 void
|
Chris@350
|
263 Transform::setWindowType(WindowType type)
|
Chris@350
|
264 {
|
Chris@350
|
265 m_windowType = type;
|
Chris@350
|
266 }
|
Chris@350
|
267
|
Chris@350
|
268 RealTime
|
Chris@350
|
269 Transform::getStartTime() const
|
Chris@350
|
270 {
|
Chris@350
|
271 return m_startTime;
|
Chris@350
|
272 }
|
Chris@350
|
273
|
Chris@350
|
274 void
|
Chris@350
|
275 Transform::setStartTime(RealTime t)
|
Chris@350
|
276 {
|
Chris@350
|
277 m_startTime = t;
|
Chris@350
|
278 }
|
Chris@350
|
279
|
Chris@350
|
280 RealTime
|
Chris@350
|
281 Transform::getDuration() const
|
Chris@350
|
282 {
|
Chris@350
|
283 return m_duration;
|
Chris@350
|
284 }
|
Chris@350
|
285
|
Chris@350
|
286 void
|
Chris@350
|
287 Transform::setDuration(RealTime d)
|
Chris@350
|
288 {
|
Chris@350
|
289 m_duration = d;
|
Chris@350
|
290 }
|
Chris@350
|
291
|
Chris@350
|
292 float
|
Chris@350
|
293 Transform::getSampleRate() const
|
Chris@350
|
294 {
|
Chris@350
|
295 return m_sampleRate;
|
Chris@350
|
296 }
|
Chris@350
|
297
|
Chris@350
|
298 void
|
Chris@350
|
299 Transform::setSampleRate(float rate)
|
Chris@350
|
300 {
|
Chris@350
|
301 m_sampleRate = rate;
|
Chris@350
|
302 }
|
Chris@350
|
303
|
Chris@350
|
304 void
|
Chris@350
|
305 Transform::toXml(QTextStream &out, QString indent, QString extraAttributes) const
|
Chris@350
|
306 {
|
Chris@350
|
307 out << indent;
|
Chris@350
|
308
|
Chris@350
|
309 bool haveContent = true;
|
Chris@350
|
310 if (m_parameters.empty() && m_configuration.empty()) haveContent = false;
|
Chris@350
|
311
|
Chris@350
|
312 out << QString("<transform id=\"%1\" program=\"%2\" stepSize=\"%3\" blockSize=\"%4\" windowType=\"%5\" startTime=\"%6\" duration=\"%7\" sampleRate=\"%8\" %9")
|
Chris@350
|
313 .arg(encodeEntities(m_id))
|
Chris@350
|
314 .arg(encodeEntities(m_program))
|
Chris@350
|
315 .arg(m_stepSize)
|
Chris@350
|
316 .arg(m_blockSize)
|
Chris@350
|
317 .arg(encodeEntities(Window<float>::getNameForType(m_windowType).c_str()))
|
Chris@350
|
318 .arg(encodeEntities(m_startTime.toString().c_str()))
|
Chris@350
|
319 .arg(encodeEntities(m_duration.toString().c_str()))
|
Chris@350
|
320 .arg(m_sampleRate)
|
Chris@350
|
321 .arg(extraAttributes);
|
Chris@350
|
322
|
Chris@350
|
323 if (haveContent) {
|
Chris@350
|
324
|
Chris@350
|
325 out << ">\n";
|
Chris@350
|
326
|
Chris@350
|
327 for (ParameterMap::const_iterator i = m_parameters.begin();
|
Chris@350
|
328 i != m_parameters.end(); ++i) {
|
Chris@350
|
329 out << indent << " "
|
Chris@350
|
330 << QString("<parameter name=\"%1\" value=\"%2\"/>\n")
|
Chris@350
|
331 .arg(encodeEntities(i->first))
|
Chris@350
|
332 .arg(i->second);
|
Chris@350
|
333 }
|
Chris@350
|
334
|
Chris@350
|
335 for (ConfigurationMap::const_iterator i = m_configuration.begin();
|
Chris@350
|
336 i != m_configuration.end(); ++i) {
|
Chris@350
|
337 out << indent << " "
|
Chris@350
|
338 << QString("<configuration name=\"%1\" value=\"%2\"/>\n")
|
Chris@350
|
339 .arg(encodeEntities(i->first))
|
Chris@350
|
340 .arg(encodeEntities(i->second));
|
Chris@350
|
341 }
|
Chris@350
|
342
|
Chris@350
|
343 out << indent << "</transform>\n";
|
Chris@350
|
344
|
Chris@350
|
345 } else {
|
Chris@350
|
346
|
Chris@350
|
347 out << "/>\n";
|
Chris@350
|
348 }
|
Chris@350
|
349 }
|
Chris@350
|
350
|
Chris@350
|
351 void
|
Chris@350
|
352 Transform::setFromXmlAttributes(const QXmlAttributes &attrs)
|
Chris@350
|
353 {
|
Chris@350
|
354 if (attrs.value("id") != "") {
|
Chris@350
|
355 setIdentifier(attrs.value("id"));
|
Chris@350
|
356 }
|
Chris@350
|
357
|
Chris@350
|
358 if (attrs.value("program") != "") {
|
Chris@350
|
359 setProgram(attrs.value("program"));
|
Chris@350
|
360 }
|
Chris@350
|
361
|
Chris@350
|
362 if (attrs.value("stepSize") != "") {
|
Chris@350
|
363 setStepSize(attrs.value("stepSize").toInt());
|
Chris@350
|
364 }
|
Chris@350
|
365
|
Chris@350
|
366 if (attrs.value("blockSize") != "") {
|
Chris@350
|
367 setBlockSize(attrs.value("blockSize").toInt());
|
Chris@350
|
368 }
|
Chris@350
|
369
|
Chris@350
|
370 if (attrs.value("windowType") != "") {
|
Chris@350
|
371 setWindowType(Window<float>::getTypeForName
|
Chris@350
|
372 (attrs.value("windowType").toStdString()));
|
Chris@350
|
373 }
|
Chris@350
|
374
|
Chris@350
|
375 if (attrs.value("startTime") != "") {
|
Chris@350
|
376 setStartTime(RealTime::fromString(attrs.value("startTime").toStdString()));
|
Chris@350
|
377 }
|
Chris@350
|
378
|
Chris@350
|
379 if (attrs.value("duration") != "") {
|
Chris@350
|
380 setStartTime(RealTime::fromString(attrs.value("duration").toStdString()));
|
Chris@350
|
381 }
|
Chris@350
|
382
|
Chris@350
|
383 if (attrs.value("sampleRate") != "") {
|
Chris@350
|
384 setSampleRate(attrs.value("sampleRate").toFloat());
|
Chris@350
|
385 }
|
Chris@350
|
386 }
|
Chris@350
|
387
|