comparison plugin/FeatureExtractionPluginAdapter.cpp @ 60:3086ff194ea0

* More structural work on feature extraction plugin C <-> C++ adapter * Allow use of LADSPA/DSSI plugins with control outputs as feature extraction plugins (DSSI with MIDI output still to come) * Reorder labels on spectrogram status box * Minor tweaks in doc etc.
author Chris Cannam
date Mon, 27 Mar 2006 15:03:02 +0000
parents 0a34d529f8e0
children
comparison
equal deleted inserted replaced
59:9705a1978ecc 60:3086ff194ea0
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 2
3 /* 3 /*
4 Sonic Visualiser 4 Sonic Visualiser
5 An audio file viewer and annotation editor. 5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London. 6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright 2006 Chris Cannam. 7 This file copyright 2006 Chris Cannam.
8 8
9 This program is free software; you can redistribute it and/or 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 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 11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file 12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information. 13 COPYING included with this distribution for more information.
14 */ 14 */
15 15
16 #include "FeatureExtractionPluginAdapter.h" 16 #include "FeatureExtractionPluginAdapter.h"
17 17
18 #include "plugins/ChromagramPlugin.h" 18 FeatureExtractionPluginAdapterBase::FeatureExtractionPluginAdapterBase() :
19 19 m_populated(false)
20 extern int blah() 20 {
21 { 21 }
22 FeatureExtractionPluginAdapter<ChromagramPlugin> adapter; 22
23 23 const SVPPluginDescriptor *
24 const SVPPluginDescriptor *desc = adapter.getDescriptor(); 24 FeatureExtractionPluginAdapterBase::getDescriptor()
25 25 {
26 SVPPluginHandle handle = desc->instantiate(desc, 48000); 26 if (m_populated) return &m_descriptor;
27 27
28 unsigned int preferredBlockSize = desc->getPreferredBlockSize(handle); 28 FeatureExtractionPlugin *plugin = createPlugin(48000);
29 29
30 SVPOutputDescriptor *od = desc->getOutputDescriptor(handle, 2); 30 m_parameters = plugin->getParameterDescriptors();
31 31 m_programs = plugin->getPrograms();
32 SVPFeatureList **feature = desc->process(handle, 0, 0, 0); 32
33 } 33 m_descriptor.name = strdup(plugin->getName().c_str());
34 34 m_descriptor.description = strdup(plugin->getDescription().c_str());
35 m_descriptor.maker = strdup(plugin->getMaker().c_str());
36 m_descriptor.pluginVersion = plugin->getPluginVersion();
37 m_descriptor.copyright = strdup(plugin->getCopyright().c_str());
38
39 m_descriptor.parameterCount = m_parameters.size();
40 m_descriptor.parameters = (const SVPParameterDescriptor **)
41 malloc(m_parameters.size() * sizeof(SVPParameterDescriptor));
42
43 for (unsigned int i = 0; i < m_parameters.size(); ++i) {
44 SVPParameterDescriptor *desc = (SVPParameterDescriptor *)
45 malloc(sizeof(SVPParameterDescriptor));
46 desc->name = strdup(m_parameters[i].name.c_str());
47 desc->description = strdup(m_parameters[i].description.c_str());
48 desc->unit = strdup(m_parameters[i].unit.c_str());
49 desc->minValue = m_parameters[i].minValue;
50 desc->maxValue = m_parameters[i].maxValue;
51 desc->defaultValue = m_parameters[i].defaultValue;
52 desc->isQuantized = m_parameters[i].isQuantized;
53 desc->quantizeStep = m_parameters[i].quantizeStep;
54 m_descriptor.parameters[i] = desc;
55 }
56
57 m_descriptor.programCount = m_programs.size();
58 m_descriptor.programs = (const char **)
59 malloc(m_programs.size() * sizeof(const char *));
60
61 for (unsigned int i = 0; i < m_programs.size(); ++i) {
62 m_descriptor.programs[i] = strdup(m_programs[i].c_str());
63 }
64
65 m_descriptor.instantiate = svpInstantiate;
66 m_descriptor.cleanup = svpCleanup;
67 m_descriptor.initialise = svpInitialise;
68 m_descriptor.reset = svpReset;
69 m_descriptor.getParameter = svpGetParameter;
70 m_descriptor.setParameter = svpSetParameter;
71 m_descriptor.getCurrentProgram = svpGetCurrentProgram;
72 m_descriptor.selectProgram = svpSelectProgram;
73 m_descriptor.getPreferredStepSize = svpGetPreferredStepSize;
74 m_descriptor.getPreferredBlockSize = svpGetPreferredBlockSize;
75 m_descriptor.getMinChannelCount = svpGetMinChannelCount;
76 m_descriptor.getMaxChannelCount = svpGetMaxChannelCount;
77 m_descriptor.getOutputCount = svpGetOutputCount;
78 m_descriptor.getOutputDescriptor = svpGetOutputDescriptor;
79 m_descriptor.releaseOutputDescriptor = svpReleaseOutputDescriptor;
80 m_descriptor.process = svpProcess;
81 m_descriptor.getRemainingFeatures = svpGetRemainingFeatures;
82 m_descriptor.releaseFeatureSet = svpReleaseFeatureSet;
83
84 m_adapterMap[&m_descriptor] = this;
85
86 delete plugin;
87
88 m_populated = true;
89 return &m_descriptor;
90 }
91
92 FeatureExtractionPluginAdapterBase::~FeatureExtractionPluginAdapterBase()
93 {
94 if (!m_populated) return;
95
96 free((void *)m_descriptor.name);
97 free((void *)m_descriptor.description);
98 free((void *)m_descriptor.maker);
99 free((void *)m_descriptor.copyright);
100
101 for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) {
102 const SVPParameterDescriptor *desc = m_descriptor.parameters[i];
103 free((void *)desc->name);
104 free((void *)desc->description);
105 free((void *)desc->unit);
106 }
107 free((void *)m_descriptor.parameters);
108
109 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) {
110 free((void *)m_descriptor.programs[i]);
111 }
112 free((void *)m_descriptor.programs);
113
114 m_adapterMap.erase(&m_descriptor);
115 }
116
117 FeatureExtractionPluginAdapterBase *
118 FeatureExtractionPluginAdapterBase::lookupAdapter(SVPPluginHandle handle)
119 {
120 AdapterMap::const_iterator i = m_adapterMap.find(handle);
121 if (i == m_adapterMap.end()) return 0;
122 return i->second;
123 }
124
125 SVPPluginHandle
126 FeatureExtractionPluginAdapterBase::svpInstantiate(const SVPPluginDescriptor *desc,
127 float inputSampleRate)
128 {
129 if (m_adapterMap.find(desc) == m_adapterMap.end()) return 0;
130 FeatureExtractionPluginAdapterBase *adapter = m_adapterMap[desc];
131 if (desc != &adapter->m_descriptor) return 0;
132
133 FeatureExtractionPlugin *plugin = adapter->createPlugin(inputSampleRate);
134 if (plugin) {
135 m_adapterMap[plugin] = adapter;
136 }
137
138 return plugin;
139 }
140
141 void
142 FeatureExtractionPluginAdapterBase::svpCleanup(SVPPluginHandle handle)
143 {
144 FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle);
145 if (!adapter) {
146 delete ((FeatureExtractionPlugin *)handle);
147 return;
148 }
149 adapter->cleanup(((FeatureExtractionPlugin *)handle));
150 }
151
152 int
153 FeatureExtractionPluginAdapterBase::svpInitialise(SVPPluginHandle handle,
154 unsigned int channels,
155 unsigned int stepSize,
156 unsigned int blockSize)
157 {
158 bool result = ((FeatureExtractionPlugin *)handle)->initialise
159 (channels, stepSize, blockSize);
160 return result ? 1 : 0;
161 }
162
163 void
164 FeatureExtractionPluginAdapterBase::svpReset(SVPPluginHandle handle)
165 {
166 ((FeatureExtractionPlugin *)handle)->reset();
167 }
168
169 float
170 FeatureExtractionPluginAdapterBase::svpGetParameter(SVPPluginHandle handle,
171 int param)
172 {
173 FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle);
174 if (!adapter) return 0.0;
175 FeatureExtractionPlugin::ParameterList &list = adapter->m_parameters;
176 return ((FeatureExtractionPlugin *)handle)->getParameter(list[param].name);
177 }
178
179 void
180 FeatureExtractionPluginAdapterBase::svpSetParameter(SVPPluginHandle handle,
181 int param, float value)
182 {
183 FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle);
184 if (!adapter) return;
185 FeatureExtractionPlugin::ParameterList &list = adapter->m_parameters;
186 ((FeatureExtractionPlugin *)handle)->setParameter(list[param].name, value);
187 }
188
189 unsigned int
190 FeatureExtractionPluginAdapterBase::svpGetCurrentProgram(SVPPluginHandle handle)
191 {
192 FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle);
193 if (!adapter) return 0;
194 FeatureExtractionPlugin::ProgramList &list = adapter->m_programs;
195 std::string program = ((FeatureExtractionPlugin *)handle)->getCurrentProgram();
196 for (unsigned int i = 0; i < list.size(); ++i) {
197 if (list[i] == program) return i;
198 }
199 return 0;
200 }
201
202 void
203 FeatureExtractionPluginAdapterBase::svpSelectProgram(SVPPluginHandle handle,
204 unsigned int program)
205 {
206 FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle);
207 if (!adapter) return;
208 FeatureExtractionPlugin::ProgramList &list = adapter->m_programs;
209 ((FeatureExtractionPlugin *)handle)->selectProgram(list[program]);
210 }
211
212 unsigned int
213 FeatureExtractionPluginAdapterBase::svpGetPreferredStepSize(SVPPluginHandle handle)
214 {
215 return ((FeatureExtractionPlugin *)handle)->getPreferredStepSize();
216 }
217
218 unsigned int
219 FeatureExtractionPluginAdapterBase::svpGetPreferredBlockSize(SVPPluginHandle handle)
220 {
221 return ((FeatureExtractionPlugin *)handle)->getPreferredBlockSize();
222 }
223
224 unsigned int
225 FeatureExtractionPluginAdapterBase::svpGetMinChannelCount(SVPPluginHandle handle)
226 {
227 return ((FeatureExtractionPlugin *)handle)->getMinChannelCount();
228 }
229
230 unsigned int
231 FeatureExtractionPluginAdapterBase::svpGetMaxChannelCount(SVPPluginHandle handle)
232 {
233 return ((FeatureExtractionPlugin *)handle)->getMaxChannelCount();
234 }
235
236 unsigned int
237 FeatureExtractionPluginAdapterBase::svpGetOutputCount(SVPPluginHandle handle)
238 {
239 FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle);
240 if (!adapter) return 0;
241 return adapter->getOutputCount((FeatureExtractionPlugin *)handle);
242 }
243
244 SVPOutputDescriptor *
245 FeatureExtractionPluginAdapterBase::svpGetOutputDescriptor(SVPPluginHandle handle,
246 unsigned int i)
247 {
248 FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle);
249 if (!adapter) return 0;
250 return adapter->getOutputDescriptor((FeatureExtractionPlugin *)handle, i);
251 }
252
253 void
254 FeatureExtractionPluginAdapterBase::svpReleaseOutputDescriptor(SVPOutputDescriptor *desc)
255 {
256 if (desc->name) free((void *)desc->name);
257 if (desc->description) free((void *)desc->description);
258 if (desc->unit) free((void *)desc->unit);
259 for (unsigned int i = 0; i < desc->valueCount; ++i) {
260 free((void *)desc->valueNames[i]);
261 }
262 if (desc->valueNames) free((void *)desc->valueNames);
263 free((void *)desc);
264 }
265
266 SVPFeatureList **
267 FeatureExtractionPluginAdapterBase::svpProcess(SVPPluginHandle handle,
268 float **inputBuffers,
269 int sec,
270 int nsec)
271 {
272 FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle);
273 if (!adapter) return 0;
274 return adapter->process((FeatureExtractionPlugin *)handle,
275 inputBuffers, sec, nsec);
276 }
277
278 SVPFeatureList **
279 FeatureExtractionPluginAdapterBase::svpGetRemainingFeatures(SVPPluginHandle handle)
280 {
281 FeatureExtractionPluginAdapterBase *adapter = lookupAdapter(handle);
282 if (!adapter) return 0;
283 return adapter->getRemainingFeatures((FeatureExtractionPlugin *)handle);
284 }
285
286 void
287 FeatureExtractionPluginAdapterBase::svpReleaseFeatureSet(SVPFeatureList **fs)
288 {
289 if (!fs) return;
290 for (unsigned int i = 0; fs[i]; ++i) {
291 for (unsigned int j = 0; j < fs[i]->featureCount; ++j) {
292 SVPFeature *feature = &fs[i]->features[j];
293 if (feature->values) free((void *)feature->values);
294 if (feature->label) free((void *)feature->label);
295 free((void *)feature);
296 }
297 if (fs[i]->features) free((void *)fs[i]->features);
298 free((void *)fs[i]);
299 }
300 free((void *)fs);
301 }
302
303 void
304 FeatureExtractionPluginAdapterBase::cleanup(FeatureExtractionPlugin *plugin)
305 {
306 if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) {
307 delete m_pluginOutputs[plugin];
308 m_pluginOutputs.erase(plugin);
309 }
310 m_adapterMap.erase(plugin);
311 delete ((FeatureExtractionPlugin *)plugin);
312 }
313
314 void
315 FeatureExtractionPluginAdapterBase::checkOutputMap(FeatureExtractionPlugin *plugin)
316 {
317 if (!m_pluginOutputs[plugin]) {
318 m_pluginOutputs[plugin] = new FeatureExtractionPlugin::OutputList
319 (plugin->getOutputDescriptors());
320 }
321 }
322
323 unsigned int
324 FeatureExtractionPluginAdapterBase::getOutputCount(FeatureExtractionPlugin *plugin)
325 {
326 checkOutputMap(plugin);
327 return m_pluginOutputs[plugin]->size();
328 }
329
330 SVPOutputDescriptor *
331 FeatureExtractionPluginAdapterBase::getOutputDescriptor(FeatureExtractionPlugin *plugin,
332 unsigned int i)
333 {
334 checkOutputMap(plugin);
335 FeatureExtractionPlugin::OutputDescriptor &od =
336 (*m_pluginOutputs[plugin])[i];
337
338 SVPOutputDescriptor *desc = (SVPOutputDescriptor *)
339 malloc(sizeof(SVPOutputDescriptor));
340
341 desc->name = strdup(od.name.c_str());
342 desc->description = strdup(od.description.c_str());
343 desc->unit = strdup(od.unit.c_str());
344 desc->hasFixedValueCount = od.hasFixedValueCount;
345 desc->valueCount = od.valueCount;
346
347 desc->valueNames = (const char **)
348 malloc(od.valueCount * sizeof(const char *));
349
350 for (unsigned int i = 0; i < od.valueCount; ++i) {
351 desc->valueNames[i] = strdup(od.valueNames[i].c_str());
352 }
353
354 desc->hasKnownExtents = od.hasKnownExtents;
355 desc->minValue = od.minValue;
356 desc->maxValue = od.maxValue;
357 desc->isQuantized = od.isQuantized;
358 desc->quantizeStep = od.quantizeStep;
359
360 switch (od.sampleType) {
361 case FeatureExtractionPlugin::OutputDescriptor::OneSamplePerStep:
362 desc->sampleType = svpOneSamplePerStep; break;
363 case FeatureExtractionPlugin::OutputDescriptor::FixedSampleRate:
364 desc->sampleType = svpFixedSampleRate; break;
365 case FeatureExtractionPlugin::OutputDescriptor::VariableSampleRate:
366 desc->sampleType = svpVariableSampleRate; break;
367 }
368
369 desc->sampleRate = od.sampleRate;
370
371 return desc;
372 }
373
374 SVPFeatureList **
375 FeatureExtractionPluginAdapterBase::process(FeatureExtractionPlugin *plugin,
376 float **inputBuffers,
377 int sec, int nsec)
378 {
379 RealTime rt(sec, nsec);
380 return convertFeatures(plugin->process(inputBuffers, rt));
381 }
382
383 SVPFeatureList **
384 FeatureExtractionPluginAdapterBase::getRemainingFeatures(FeatureExtractionPlugin *plugin)
385 {
386 return convertFeatures(plugin->getRemainingFeatures());
387 }
388
389 SVPFeatureList **
390 FeatureExtractionPluginAdapterBase::convertFeatures(const FeatureExtractionPlugin::FeatureSet &features)
391 {
392 unsigned int n = 0;
393 if (features.begin() != features.end()) {
394 FeatureExtractionPlugin::FeatureSet::const_iterator i = features.end();
395 --i;
396 n = i->first + 1;
397 }
398
399 if (!n) return 0;
400
401 SVPFeatureList **fs = (SVPFeatureList **)
402 malloc((n + 1) * sizeof(SVPFeatureList *));
403
404 for (unsigned int i = 0; i < n; ++i) {
405 fs[i] = (SVPFeatureList *)malloc(sizeof(SVPFeatureList));
406 if (features.find(i) == features.end()) {
407 fs[i]->featureCount = 0;
408 fs[i]->features = 0;
409 } else {
410 FeatureExtractionPlugin::FeatureSet::const_iterator fi =
411 features.find(i);
412 const FeatureExtractionPlugin::FeatureList &fl = fi->second;
413 fs[i]->featureCount = fl.size();
414 fs[i]->features = (SVPFeature *)malloc(fl.size() *
415 sizeof(SVPFeature));
416 for (unsigned int j = 0; j < fl.size(); ++j) {
417 fs[i]->features[j].hasTimestamp = fl[j].hasTimestamp;
418 fs[i]->features[j].sec = fl[j].timestamp.sec;
419 fs[i]->features[j].nsec = fl[j].timestamp.nsec;
420 fs[i]->features[j].valueCount = fl[j].values.size();
421 fs[i]->features[j].values = (float *)malloc
422 (fs[i]->features[j].valueCount * sizeof(float));
423 for (unsigned int k = 0; k < fs[i]->features[j].valueCount; ++k) {
424 fs[i]->features[j].values[k] = fl[j].values[k];
425 }
426 fs[i]->features[j].label = strdup(fl[j].label.c_str());
427 }
428 }
429 }
430
431 fs[n] = 0;
432
433 return fs;
434 }
435
436 FeatureExtractionPluginAdapterBase::AdapterMap
437 FeatureExtractionPluginAdapterBase::m_adapterMap;
438
439