comparison capnproto/VampnProto.h @ 5:6e8607ebad03

Promote the more successful experiments (todo: get them to build again)
author Chris Cannam <c.cannam@qmul.ac.uk>
date Fri, 13 May 2016 13:48:59 +0100
parents
children d8358afe3f2c
comparison
equal deleted inserted replaced
4:25499f505d0e 5:6e8607ebad03
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 #include "vamp.capnp.h"
4
5 #include <capnp/message.h>
6 #include <capnp/serialize-packed.h>
7
8 #include <vamp-hostsdk/Plugin.h>
9 #include <vamp-hostsdk/PluginLoader.h>
10 #include <vamp-hostsdk/PluginStaticData.h>
11
12 namespace vampipe
13 {
14
15 /**
16 * Convert the structures laid out in the Vamp SDK classes into Cap'n
17 * Proto structures.
18 *
19 * At least some of this will be necessary for any implementation that
20 * is using the C++ Vamp SDK to provide its reference structures. An
21 * implementation could alternatively use the Cap'n Proto structures
22 * directly, and interact with Vamp plugins using the Vamp C API,
23 * without using the C++ Vamp SDK classes at all.
24 */
25
26 class VampSDKConverter
27 {
28 public:
29 typedef ::capnp::MallocMessageBuilder MsgBuilder;
30
31 template <typename T, typename B>
32 static void buildBasicDescriptor(B &basic, const T &t) {
33 basic.setIdentifier(t.identifier);
34 basic.setName(t.name);
35 basic.setDescription(t.description);
36 }
37
38 template <typename T, typename B>
39 static void readBasicDescriptor(T &t, const B &basic) {
40 t.identifier = basic.getIdentifier();
41 t.name = basic.getName();
42 t.description = basic.getDescription();
43 }
44
45 template <typename T, typename M>
46 static void buildValueExtents(M &m, const T &t) {
47 m.setMinValue(t.minValue);
48 m.setMaxValue(t.maxValue);
49 }
50
51 template <typename T, typename M>
52 static void readValueExtents(T &t, const M &m) {
53 t.minValue = m.getMinValue();
54 t.maxValue = m.getMaxValue();
55 }
56
57 static void buildRealTime(RealTime::Builder &b, const Vamp::RealTime &t) {
58 b.setSec(t.sec);
59 b.setNsec(t.nsec);
60 }
61
62 static void readRealTime(Vamp::RealTime &t, const RealTime::Reader &r) {
63 t.sec = r.getSec();
64 t.nsec = r.getNsec();
65 }
66
67 static SampleType
68 fromSampleType(Vamp::Plugin::OutputDescriptor::SampleType t) {
69 switch (t) {
70 case Vamp::Plugin::OutputDescriptor::OneSamplePerStep:
71 return SampleType::ONE_SAMPLE_PER_STEP;
72 case Vamp::Plugin::OutputDescriptor::FixedSampleRate:
73 return SampleType::FIXED_SAMPLE_RATE;
74 case Vamp::Plugin::OutputDescriptor::VariableSampleRate:
75 return SampleType::VARIABLE_SAMPLE_RATE;
76 }
77 throw std::logic_error("unexpected Vamp SampleType enum value");
78 }
79
80 static Vamp::Plugin::OutputDescriptor::SampleType
81 toSampleType(SampleType t) {
82 switch (t) {
83 case SampleType::ONE_SAMPLE_PER_STEP:
84 return Vamp::Plugin::OutputDescriptor::OneSamplePerStep;
85 case SampleType::FIXED_SAMPLE_RATE:
86 return Vamp::Plugin::OutputDescriptor::FixedSampleRate;
87 case SampleType::VARIABLE_SAMPLE_RATE:
88 return Vamp::Plugin::OutputDescriptor::VariableSampleRate;
89 }
90 throw std::logic_error("unexpected Capnp SampleType enum value");
91 }
92
93 static void
94 buildOutputDescriptor(OutputDescriptor::Builder &b,
95 const Vamp::Plugin::OutputDescriptor &od) {
96
97 auto basic = b.initBasic();
98 buildBasicDescriptor(basic, od);
99
100 b.setUnit(od.unit);
101
102 b.setSampleType(fromSampleType(od.sampleType));
103 b.setSampleRate(od.sampleRate);
104 b.setHasDuration(od.hasDuration);
105
106 b.setHasFixedBinCount(od.hasFixedBinCount);
107 if (od.hasFixedBinCount) {
108 b.setBinCount(od.binCount);
109 if (od.binNames.size() > 0) {
110 auto binNames = b.initBinNames(od.binNames.size());
111 for (size_t i = 0; i < od.binNames.size(); ++i) {
112 binNames.set(i, od.binNames[i]);
113 }
114 }
115 }
116
117 b.setHasKnownExtents(od.hasKnownExtents);
118 if (od.hasKnownExtents) {
119 buildValueExtents(b, od);
120 }
121
122 b.setIsQuantized(od.isQuantized);
123 if (od.isQuantized) {
124 b.setQuantizeStep(od.quantizeStep);
125 }
126 }
127
128 static void
129 readOutputDescriptor(Vamp::Plugin::OutputDescriptor &od,
130 const OutputDescriptor::Reader &r) {
131
132 readBasicDescriptor(od, r.getBasic());
133
134 od.unit = r.getUnit();
135
136 od.sampleType = toSampleType(r.getSampleType());
137 od.sampleRate = r.getSampleRate();
138 od.hasDuration = r.getHasDuration();
139
140 od.hasFixedBinCount = r.getHasFixedBinCount();
141 if (od.hasFixedBinCount) {
142 od.binCount = r.getBinCount();
143 for (const auto &n: r.getBinNames()) {
144 od.binNames.push_back(n);
145 }
146 }
147
148 od.hasKnownExtents = r.getHasKnownExtents();
149 if (od.hasKnownExtents) {
150 readValueExtents(od, r);
151 }
152
153 od.isQuantized = r.getIsQuantized();
154 if (od.isQuantized) {
155 od.quantizeStep = r.getQuantizeStep();
156 }
157 }
158
159 static void
160 buildParameterDescriptor(ParameterDescriptor::Builder &b,
161 const Vamp::Plugin::ParameterDescriptor &pd) {
162
163 auto basic = b.initBasic();
164 buildBasicDescriptor(basic, pd);
165
166 b.setUnit(pd.unit);
167
168 buildValueExtents(b, pd);
169
170 b.setDefaultValue(pd.defaultValue);
171
172 b.setIsQuantized(pd.isQuantized);
173 if (pd.isQuantized) {
174 b.setQuantizeStep(pd.quantizeStep);
175 }
176
177 if (pd.valueNames.size() > 0) {
178 auto valueNames = b.initValueNames(pd.valueNames.size());
179 for (size_t i = 0; i < pd.valueNames.size(); ++i) {
180 valueNames.set(i, pd.valueNames[i]);
181 }
182 }
183 }
184
185 static void
186 readParameterDescriptor(Vamp::Plugin::ParameterDescriptor &pd,
187 const ParameterDescriptor::Reader &r) {
188
189 readBasicDescriptor(pd, r.getBasic());
190
191 pd.unit = r.getUnit();
192
193 readValueExtents(pd, r);
194
195 pd.defaultValue = r.getDefaultValue();
196
197 pd.isQuantized = r.getIsQuantized();
198 if (pd.isQuantized) {
199 pd.quantizeStep = r.getQuantizeStep();
200 }
201
202 for (const auto &n: r.getValueNames()) {
203 pd.valueNames.push_back(n);
204 }
205 }
206
207 static void
208 buildFeature(Feature::Builder &b,
209 const Vamp::Plugin::Feature &f) {
210
211 b.setHasTimestamp(f.hasTimestamp);
212 if (f.hasTimestamp) {
213 auto timestamp = b.initTimestamp();
214 buildRealTime(timestamp, f.timestamp);
215 }
216
217 b.setHasDuration(f.hasDuration);
218 if (f.hasDuration) {
219 auto duration = b.initDuration();
220 buildRealTime(duration, f.duration);
221 }
222
223 b.setLabel(f.label);
224
225 if (f.values.size() > 0) {
226 auto values = b.initValues(f.values.size());
227 for (size_t i = 0; i < f.values.size(); ++i) {
228 values.set(i, f.values[i]);
229 }
230 }
231 }
232
233 static void
234 readFeature(Vamp::Plugin::Feature &f,
235 const Feature::Reader &r) {
236
237 f.hasTimestamp = r.getHasTimestamp();
238 if (f.hasTimestamp) {
239 readRealTime(f.timestamp, r.getTimestamp());
240 }
241
242 f.hasDuration = r.getHasDuration();
243 if (f.hasDuration) {
244 readRealTime(f.duration, r.getDuration());
245 }
246
247 f.label = r.getLabel();
248
249 for (auto v: r.getValues()) {
250 f.values.push_back(v);
251 }
252 }
253
254 static void
255 buildFeatureSet(FeatureSet::Builder &b,
256 const Vamp::Plugin::FeatureSet &fs) {
257
258 auto featureset = b.initFeaturePairs(fs.size());
259 int ix = 0;
260 for (const auto &fsi : fs) {
261 auto fspair = featureset[ix];
262 fspair.setOutput(fsi.first);
263 auto featurelist = fspair.initFeatures(fsi.second.size());
264 for (size_t j = 0; j < fsi.second.size(); ++j) {
265 auto feature = featurelist[j];
266 buildFeature(feature, fsi.second[j]);
267 }
268 ++ix;
269 }
270 }
271
272 static void
273 readFeatureSet(Vamp::Plugin::FeatureSet &fs,
274 const FeatureSet::Reader &r) {
275
276 for (const auto &p: r.getFeaturePairs()) {
277 Vamp::Plugin::FeatureList vfl;
278 for (const auto &f: p.getFeatures()) {
279 Vamp::Plugin::Feature vf;
280 readFeature(vf, f);
281 vfl.push_back(vf);
282 }
283 fs[p.getOutput()] = vfl;
284 }
285 }
286
287 static InputDomain
288 fromInputDomain(Vamp::Plugin::InputDomain d) {
289 switch(d) {
290 case Vamp::Plugin::TimeDomain:
291 return InputDomain::TIME_DOMAIN;
292 case Vamp::Plugin::FrequencyDomain:
293 return InputDomain::FREQUENCY_DOMAIN;
294 default:
295 throw std::logic_error("unexpected Vamp InputDomain enum value");
296 }
297 }
298
299 static Vamp::Plugin::InputDomain
300 toInputDomain(InputDomain d) {
301 switch(d) {
302 case InputDomain::TIME_DOMAIN:
303 return Vamp::Plugin::TimeDomain;
304 case InputDomain::FREQUENCY_DOMAIN:
305 return Vamp::Plugin::FrequencyDomain;
306 default:
307 throw std::logic_error("unexpected Capnp InputDomain enum value");
308 }
309 }
310
311 static void
312 buildPluginStaticData(PluginStaticData::Builder &b,
313 const Vamp::HostExt::PluginStaticData &d) {
314
315 b.setPluginKey(d.pluginKey);
316
317 auto basic = b.initBasic();
318 buildBasicDescriptor(basic, d.basic);
319
320 b.setMaker(d.maker);
321 b.setCopyright(d.copyright);
322 b.setPluginVersion(d.pluginVersion);
323
324 auto clist = b.initCategory(d.category.size());
325 for (size_t i = 0; i < d.category.size(); ++i) {
326 clist.set(i, d.category[i]);
327 }
328
329 b.setMinChannelCount(d.minChannelCount);
330 b.setMaxChannelCount(d.maxChannelCount);
331
332 const auto &vparams = d.parameters;
333 auto plist = b.initParameters(vparams.size());
334 for (size_t i = 0; i < vparams.size(); ++i) {
335 auto pd = plist[i];
336 buildParameterDescriptor(pd, vparams[i]);
337 }
338
339 const auto &vprogs = d.programs;
340 auto pglist = b.initPrograms(vprogs.size());
341 for (size_t i = 0; i < vprogs.size(); ++i) {
342 pglist.set(i, vprogs[i]);
343 }
344
345 b.setInputDomain(fromInputDomain(d.inputDomain));
346
347 const auto &vouts = d.basicOutputInfo;
348 auto olist = b.initBasicOutputInfo(vouts.size());
349 for (size_t i = 0; i < vouts.size(); ++i) {
350 auto od = olist[i];
351 buildBasicDescriptor(od, vouts[i]);
352 }
353 }
354
355 static void
356 readPluginStaticData(Vamp::HostExt::PluginStaticData &d,
357 const PluginStaticData::Reader &r) {
358
359 d.pluginKey = r.getPluginKey();
360
361 readBasicDescriptor(d.basic, r.getBasic());
362
363 d.maker = r.getMaker();
364 d.copyright = r.getCopyright();
365 d.pluginVersion = r.getPluginVersion();
366
367 for (auto c: r.getCategory()) {
368 d.category.push_back(c);
369 }
370
371 d.minChannelCount = r.getMinChannelCount();
372 d.maxChannelCount = r.getMaxChannelCount();
373
374 for (auto p: r.getParameters()) {
375 Vamp::Plugin::ParameterDescriptor pd;
376 readParameterDescriptor(pd, p);
377 d.parameters.push_back(pd);
378 }
379
380 for (auto p: r.getPrograms()) {
381 d.programs.push_back(p);
382 }
383
384 d.inputDomain = toInputDomain(r.getInputDomain());
385
386 for (auto o: r.getBasicOutputInfo()) {
387 Vamp::HostExt::PluginStaticData::Basic b;
388 readBasicDescriptor(b, o);
389 d.basicOutputInfo.push_back(b);
390 }
391 }
392
393 static void
394 buildPluginConfiguration(PluginConfiguration::Builder &b,
395 const Vamp::HostExt::PluginConfiguration &c) {
396
397 const auto &vparams = c.parameterValues;
398 auto params = b.initParameterValues(vparams.size());
399 int i = 0;
400 for (const auto &pp : vparams) {
401 auto param = params[i++];
402 param.setParameter(pp.first);
403 param.setValue(pp.second);
404 }
405
406 b.setCurrentProgram(c.currentProgram);
407 b.setChannelCount(c.channelCount);
408 b.setStepSize(c.stepSize);
409 b.setBlockSize(c.blockSize);
410 }
411
412 static void
413 readPluginConfiguration(Vamp::HostExt::PluginConfiguration &c,
414 const PluginConfiguration::Reader &r) {
415
416 for (const auto &pp: r.getParameterValues()) {
417 c.parameterValues[pp.getParameter()] = pp.getValue();
418 }
419
420 c.currentProgram = r.getCurrentProgram();
421 c.channelCount = r.getChannelCount();
422 c.stepSize = r.getStepSize();
423 c.blockSize = r.getBlockSize();
424 }
425
426 static void
427 buildLoadRequest(LoadRequest::Builder &r,
428 const Vamp::HostExt::LoadRequest &req) {
429
430 r.setPluginKey(req.pluginKey);
431 r.setInputSampleRate(req.inputSampleRate);
432
433 std::vector<AdapterFlag> flags;
434 if (req.adapterFlags & Vamp::HostExt::PluginLoader::ADAPT_INPUT_DOMAIN) {
435 flags.push_back(AdapterFlag::ADAPT_INPUT_DOMAIN);
436 }
437 if (req.adapterFlags & Vamp::HostExt::PluginLoader::ADAPT_CHANNEL_COUNT) {
438 flags.push_back(AdapterFlag::ADAPT_CHANNEL_COUNT);
439 }
440 if (req.adapterFlags & Vamp::HostExt::PluginLoader::ADAPT_BUFFER_SIZE) {
441 flags.push_back(AdapterFlag::ADAPT_BUFFER_SIZE);
442 }
443
444 auto f = r.initAdapterFlags(flags.size());
445 for (size_t i = 0; i < flags.size(); ++i) {
446 f.set(i, flags[i]);
447 }
448 }
449
450 static void
451 readLoadRequest(Vamp::HostExt::LoadRequest &req,
452 const LoadRequest::Reader &r) {
453
454 req.pluginKey = r.getPluginKey();
455 req.inputSampleRate = r.getInputSampleRate();
456
457 int flags = 0;
458 for (const auto &a: r.getAdapterFlags()) {
459 if (a == AdapterFlag::ADAPT_INPUT_DOMAIN) {
460 flags |= Vamp::HostExt::PluginLoader::ADAPT_INPUT_DOMAIN;
461 }
462 if (a == AdapterFlag::ADAPT_CHANNEL_COUNT) {
463 flags |= Vamp::HostExt::PluginLoader::ADAPT_CHANNEL_COUNT;
464 }
465 if (a == AdapterFlag::ADAPT_BUFFER_SIZE) {
466 flags |= Vamp::HostExt::PluginLoader::ADAPT_BUFFER_SIZE;
467 }
468 }
469 req.adapterFlags = flags;
470 }
471 };
472
473 }
474
475