comparison plugin/PluginXml.cpp @ 66:7afcfe666910

* Modify to use Vamp SDK for proper feature extraction plugins. Requires that the vamp-plugin-sdk directory tree be present below plugin/ (it's separate in Subversion).
author Chris Cannam
date Fri, 31 Mar 2006 15:56:35 +0000
parents
children 163f3428bbe0
comparison
equal deleted inserted replaced
65:e1aad27029e3 66:7afcfe666910
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Sonic Visualiser
5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright 2006 Chris Cannam.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information.
14 */
15
16 #include "PluginXml.h"
17
18 #include <QRegExp>
19 #include <QXmlAttributes>
20
21 #include <QDomDocument>
22 #include <QDomElement>
23 #include <QDomNamedNodeMap>
24 #include <QDomAttr>
25
26 #include "vamp-sdk/PluginBase.h"
27
28 #include <iostream>
29
30 PluginXml::PluginXml(Vamp::PluginBase *plugin) :
31 m_plugin(plugin)
32 {
33 }
34
35 PluginXml::~PluginXml() { }
36
37 QString
38 PluginXml::toXmlString(QString indent, QString extraAttributes) const
39 {
40 QString s;
41 s += indent;
42
43 s += QString("<plugin name=\"%1\" description=\"%2\" maker=\"%3\" version=\"%4\" copyright=\"%5\" %6 ")
44 .arg(encodeEntities(QString(m_plugin->getName().c_str())))
45 .arg(encodeEntities(QString(m_plugin->getDescription().c_str())))
46 .arg(encodeEntities(QString(m_plugin->getMaker().c_str())))
47 .arg(m_plugin->getPluginVersion())
48 .arg(encodeEntities(QString(m_plugin->getCopyright().c_str())))
49 .arg(extraAttributes);
50
51 if (!m_plugin->getPrograms().empty()) {
52 s += QString("program=\"%1\" ")
53 .arg(encodeEntities(m_plugin->getCurrentProgram().c_str()));
54 }
55
56 Vamp::PluginBase::ParameterList parameters =
57 m_plugin->getParameterDescriptors();
58
59 for (Vamp::PluginBase::ParameterList::const_iterator i = parameters.begin();
60 i != parameters.end(); ++i) {
61 s += QString("param-%1=\"%2\" ")
62 .arg(stripInvalidParameterNameCharacters(QString(i->name.c_str())))
63 .arg(m_plugin->getParameter(i->name));
64 }
65
66 s += "/>\n";
67 return s;
68 }
69
70 #define CHECK_ATTRIBUTE(ATTRIBUTE, ACCESSOR) \
71 QString ATTRIBUTE = attrs.value(#ATTRIBUTE); \
72 if (ATTRIBUTE != "" && ATTRIBUTE != ACCESSOR().c_str()) { \
73 std::cerr << "WARNING: PluginXml::setParameters: Plugin " \
74 << #ATTRIBUTE << " does not match (attributes have \"" \
75 << ATTRIBUTE.toStdString() << "\", my " \
76 << #ATTRIBUTE << " is \"" << ACCESSOR() << "\")" << std::endl; \
77 }
78
79 void
80 PluginXml::setParameters(const QXmlAttributes &attrs)
81 {
82 CHECK_ATTRIBUTE(name, m_plugin->getName);
83 CHECK_ATTRIBUTE(description, m_plugin->getDescription);
84 CHECK_ATTRIBUTE(maker, m_plugin->getMaker);
85 CHECK_ATTRIBUTE(copyright, m_plugin->getCopyright);
86
87 bool ok;
88 int version = attrs.value("version").trimmed().toInt(&ok);
89 if (ok && version != m_plugin->getPluginVersion()) {
90 std::cerr << "WARNING: PluginXml::setParameters: Plugin version does not match (attributes have " << version << ", my version is " << m_plugin->getPluginVersion() << ")" << std::endl;
91 }
92
93 if (!m_plugin->getPrograms().empty()) {
94 m_plugin->selectProgram(attrs.value("program").toStdString());
95 }
96
97 Vamp::PluginBase::ParameterList parameters =
98 m_plugin->getParameterDescriptors();
99
100 for (Vamp::PluginBase::ParameterList::const_iterator i =
101 parameters.begin(); i != parameters.end(); ++i) {
102
103 QString name = QString("param-%1")
104 .arg(stripInvalidParameterNameCharacters
105 (QString(i->name.c_str())));
106
107 if (attrs.value(name) == "") {
108 std::cerr << "PluginXml::setParameters: no parameter \"" << i->name << "\" (attribute \"" << name.toStdString() << "\")" << std::endl;
109 continue;
110 }
111
112 bool ok;
113 float value = attrs.value(name).trimmed().toFloat(&ok);
114 if (ok) {
115 m_plugin->setParameter(i->name, value);
116 } else {
117 std::cerr << "WARNING: PluginXml::setParameters: Invalid value \"" << attrs.value(name).toStdString() << "\" for parameter \"" << i->name << "\" (attribute \"" << name.toStdString() << "\")" << std::endl;
118 }
119 }
120 }
121
122 void
123 PluginXml::setParametersFromXml(QString xml)
124 {
125 QDomDocument doc;
126
127 QString error;
128 int errorLine;
129 int errorColumn;
130
131 if (!doc.setContent(xml, false, &error, &errorLine, &errorColumn)) {
132 std::cerr << "PluginXml::setParametersFromXml: Error in parsing XML: " << error.toStdString() << " at line " << errorLine << ", column " << errorColumn << std::endl;
133 std::cerr << "Input follows:" << std::endl;
134 std::cerr << xml.toStdString() << std::endl;
135 std::cerr << "Input ends." << std::endl;
136 return;
137 }
138
139 QDomElement pluginElt = doc.firstChildElement("plugin");
140 QDomNamedNodeMap attrNodes = pluginElt.attributes();
141 QXmlAttributes attrs;
142
143 for (unsigned int i = 0; i < attrNodes.length(); ++i) {
144 QDomAttr attr = attrNodes.item(i).toAttr();
145 if (attr.isNull()) continue;
146 std::cerr << "Adding attribute \"" << attr.name().toStdString()
147 << "\" with value \"" << attr.value().toStdString() << "\"" << std::endl;
148 attrs.append(attr.name(), "", "", attr.value());
149 }
150
151 setParameters(attrs);
152 }
153
154 QString
155 PluginXml::stripInvalidParameterNameCharacters(QString s) const
156 {
157 s.replace(QRegExp("[^a-zA-Z0-9_]*"), "");
158 return s;
159 }
160