comparison vamp-capnp/VampnProto.h @ 75:81e1c48e97f9

Rearrange and rename to Piper C++ structure
author Chris Cannam <c.cannam@qmul.ac.uk>
date Mon, 10 Oct 2016 16:31:09 +0100
parents
children 5909d5d25733
comparison
equal deleted inserted replaced
74:d45cfa25aaad 75:81e1c48e97f9
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Piper C++
5
6 Centre for Digital Music, Queen Mary, University of London.
7 Copyright 2015-2016 QMUL.
8
9 Permission is hereby granted, free of charge, to any person
10 obtaining a copy of this software and associated documentation
11 files (the "Software"), to deal in the Software without
12 restriction, including without limitation the rights to use, copy,
13 modify, merge, publish, distribute, sublicense, and/or sell copies
14 of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be
18 included in all copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
24 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
25 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 Except as contained in this notice, the names of the Centre for
29 Digital Music; Queen Mary, University of London; and Chris Cannam
30 shall not be used in advertising or otherwise to promote the sale,
31 use or other dealings in this Software without prior written
32 authorization.
33 */
34
35 #include "piper.capnp.h"
36
37 #include <capnp/message.h>
38 #include <capnp/serialize-packed.h>
39
40 #include <vamp-hostsdk/Plugin.h>
41 #include <vamp-hostsdk/PluginLoader.h>
42 #include <vamp-hostsdk/PluginStaticData.h>
43
44 #include "vamp-support/PluginHandleMapper.h"
45 #include "vamp-support/PluginOutputIdMapper.h"
46 #include "vamp-support/RequestResponseType.h"
47
48 namespace piper
49 {
50
51 /**
52 * Convert the structures laid out in the Vamp SDK classes into Cap'n
53 * Proto structures (and back again).
54 *
55 * At least some of this will be necessary for any implementation
56 * using Cap'n Proto that uses the C++ Vamp SDK to provide its
57 * reference structures. An implementation could alternatively use the
58 * Cap'n Proto structures directly, and interact with Vamp plugins
59 * using the Vamp C API, without using the C++ Vamp SDK classes at
60 * all. That would avoid a lot of copying (in Cap'n Proto style).
61 */
62 class VampnProto
63 {
64 public:
65 typedef ::capnp::MallocMessageBuilder MsgBuilder;
66
67 template <typename T, typename B>
68 static void buildBasicDescriptor(B &basic, const T &t) {
69 basic.setIdentifier(t.identifier);
70 basic.setName(t.name);
71 basic.setDescription(t.description);
72 }
73
74 template <typename T, typename B>
75 static void readBasicDescriptor(T &t, const B &basic) {
76 t.identifier = basic.getIdentifier();
77 t.name = basic.getName();
78 t.description = basic.getDescription();
79 }
80
81 template <typename T, typename M>
82 static void buildValueExtents(M &m, const T &t) {
83 m.setMinValue(t.minValue);
84 m.setMaxValue(t.maxValue);
85 }
86
87 template <typename T, typename M>
88 static void readValueExtents(T &t, const M &m) {
89 t.minValue = m.getMinValue();
90 t.maxValue = m.getMaxValue();
91 }
92
93 static void buildRealTime(RealTime::Builder &b, const Vamp::RealTime &t) {
94 b.setSec(t.sec);
95 b.setNsec(t.nsec);
96 }
97
98 static void readRealTime(Vamp::RealTime &t, const RealTime::Reader &r) {
99 t.sec = r.getSec();
100 t.nsec = r.getNsec();
101 }
102
103 static SampleType
104 fromSampleType(Vamp::Plugin::OutputDescriptor::SampleType t) {
105 switch (t) {
106 case Vamp::Plugin::OutputDescriptor::OneSamplePerStep:
107 return SampleType::ONE_SAMPLE_PER_STEP;
108 case Vamp::Plugin::OutputDescriptor::FixedSampleRate:
109 return SampleType::FIXED_SAMPLE_RATE;
110 case Vamp::Plugin::OutputDescriptor::VariableSampleRate:
111 return SampleType::VARIABLE_SAMPLE_RATE;
112 }
113 throw std::logic_error("unexpected Vamp SampleType enum value");
114 }
115
116 static Vamp::Plugin::OutputDescriptor::SampleType
117 toSampleType(SampleType t) {
118 switch (t) {
119 case SampleType::ONE_SAMPLE_PER_STEP:
120 return Vamp::Plugin::OutputDescriptor::OneSamplePerStep;
121 case SampleType::FIXED_SAMPLE_RATE:
122 return Vamp::Plugin::OutputDescriptor::FixedSampleRate;
123 case SampleType::VARIABLE_SAMPLE_RATE:
124 return Vamp::Plugin::OutputDescriptor::VariableSampleRate;
125 }
126 throw std::logic_error("unexpected Capnp SampleType enum value");
127 }
128
129 static void
130 buildConfiguredOutputDescriptor(ConfiguredOutputDescriptor::Builder &b,
131 const Vamp::Plugin::OutputDescriptor &od) {
132
133 b.setUnit(od.unit);
134
135 b.setSampleType(fromSampleType(od.sampleType));
136 b.setSampleRate(od.sampleRate);
137 b.setHasDuration(od.hasDuration);
138
139 b.setHasFixedBinCount(od.hasFixedBinCount);
140 if (od.hasFixedBinCount) {
141 b.setBinCount(od.binCount);
142 if (od.binNames.size() > 0) {
143 auto binNames = b.initBinNames(od.binNames.size());
144 for (size_t i = 0; i < od.binNames.size(); ++i) {
145 binNames.set(i, od.binNames[i]);
146 }
147 }
148 }
149
150 b.setHasKnownExtents(od.hasKnownExtents);
151 if (od.hasKnownExtents) {
152 buildValueExtents(b, od);
153 }
154
155 b.setIsQuantized(od.isQuantized);
156 if (od.isQuantized) {
157 b.setQuantizeStep(od.quantizeStep);
158 }
159 }
160
161 static void
162 buildOutputDescriptor(OutputDescriptor::Builder &b,
163 const Vamp::Plugin::OutputDescriptor &od) {
164
165 auto basic = b.initBasic();
166 buildBasicDescriptor(basic, od);
167
168 auto configured = b.initConfigured();
169 buildConfiguredOutputDescriptor(configured, od);
170 }
171
172 static void
173 readConfiguredOutputDescriptor(Vamp::Plugin::OutputDescriptor &od,
174 const ConfiguredOutputDescriptor::Reader &r) {
175
176 od.unit = r.getUnit();
177
178 od.sampleType = toSampleType(r.getSampleType());
179 od.sampleRate = r.getSampleRate();
180 od.hasDuration = r.getHasDuration();
181
182 od.hasFixedBinCount = r.getHasFixedBinCount();
183 if (od.hasFixedBinCount) {
184 od.binCount = r.getBinCount();
185 od.binNames.clear();
186 auto nn = r.getBinNames();
187 for (const auto &n: nn) {
188 od.binNames.push_back(n);
189 }
190 }
191
192 od.hasKnownExtents = r.getHasKnownExtents();
193 if (od.hasKnownExtents) {
194 readValueExtents(od, r);
195 }
196
197 od.isQuantized = r.getIsQuantized();
198 if (od.isQuantized) {
199 od.quantizeStep = r.getQuantizeStep();
200 }
201 }
202
203 static void
204 readOutputDescriptor(Vamp::Plugin::OutputDescriptor &od,
205 const OutputDescriptor::Reader &r) {
206
207 readBasicDescriptor(od, r.getBasic());
208 readConfiguredOutputDescriptor(od, r.getConfigured());
209 }
210
211 static void
212 buildParameterDescriptor(ParameterDescriptor::Builder &b,
213 const Vamp::Plugin::ParameterDescriptor &pd) {
214
215 auto basic = b.initBasic();
216 buildBasicDescriptor(basic, pd);
217
218 b.setUnit(pd.unit);
219
220 buildValueExtents(b, pd);
221
222 b.setDefaultValue(pd.defaultValue);
223
224 b.setIsQuantized(pd.isQuantized);
225 if (pd.isQuantized) {
226 b.setQuantizeStep(pd.quantizeStep);
227 }
228
229 if (pd.valueNames.size() > 0) {
230 auto valueNames = b.initValueNames(pd.valueNames.size());
231 for (size_t i = 0; i < pd.valueNames.size(); ++i) {
232 valueNames.set(i, pd.valueNames[i]);
233 }
234 }
235 }
236
237 static void
238 readParameterDescriptor(Vamp::Plugin::ParameterDescriptor &pd,
239 const ParameterDescriptor::Reader &r) {
240
241 readBasicDescriptor(pd, r.getBasic());
242
243 pd.unit = r.getUnit();
244
245 readValueExtents(pd, r);
246
247 pd.defaultValue = r.getDefaultValue();
248
249 pd.isQuantized = r.getIsQuantized();
250 if (pd.isQuantized) {
251 pd.quantizeStep = r.getQuantizeStep();
252 }
253
254 pd.valueNames.clear();
255 auto nn = r.getValueNames();
256 for (const auto &n: nn) {
257 pd.valueNames.push_back(n);
258 }
259 }
260
261 static void
262 buildFeature(Feature::Builder &b,
263 const Vamp::Plugin::Feature &f) {
264
265 b.setHasTimestamp(f.hasTimestamp);
266 if (f.hasTimestamp) {
267 auto timestamp = b.initTimestamp();
268 buildRealTime(timestamp, f.timestamp);
269 }
270
271 b.setHasDuration(f.hasDuration);
272 if (f.hasDuration) {
273 auto duration = b.initDuration();
274 buildRealTime(duration, f.duration);
275 }
276
277 b.setLabel(f.label);
278
279 if (f.values.size() > 0) {
280 auto values = b.initFeatureValues(f.values.size());
281 for (size_t i = 0; i < f.values.size(); ++i) {
282 values.set(i, f.values[i]);
283 }
284 }
285 }
286
287 static void
288 readFeature(Vamp::Plugin::Feature &f,
289 const Feature::Reader &r) {
290
291 f.hasTimestamp = r.getHasTimestamp();
292 if (f.hasTimestamp) {
293 readRealTime(f.timestamp, r.getTimestamp());
294 }
295
296 f.hasDuration = r.getHasDuration();
297 if (f.hasDuration) {
298 readRealTime(f.duration, r.getDuration());
299 }
300
301 f.label = r.getLabel();
302
303 f.values.clear();
304 auto vv = r.getFeatureValues();
305 for (auto v: vv) {
306 f.values.push_back(v);
307 }
308 }
309
310 static void
311 buildFeatureSet(FeatureSet::Builder &b,
312 const Vamp::Plugin::FeatureSet &fs,
313 const PluginOutputIdMapper &omapper) {
314
315 auto featureset = b.initFeaturePairs(fs.size());
316 int ix = 0;
317 for (const auto &fsi : fs) {
318 auto fspair = featureset[ix];
319 fspair.setOutput(omapper.indexToId(fsi.first));
320 auto featurelist = fspair.initFeatures(fsi.second.size());
321 for (size_t j = 0; j < fsi.second.size(); ++j) {
322 auto feature = featurelist[j];
323 buildFeature(feature, fsi.second[j]);
324 }
325 ++ix;
326 }
327 }
328
329 static void
330 readFeatureSet(Vamp::Plugin::FeatureSet &fs,
331 const FeatureSet::Reader &r,
332 const PluginOutputIdMapper &omapper) {
333
334 fs.clear();
335 auto pp = r.getFeaturePairs();
336 for (const auto &p: pp) {
337 Vamp::Plugin::FeatureList vfl;
338 auto ff = p.getFeatures();
339 for (const auto &f: ff) {
340 Vamp::Plugin::Feature vf;
341 readFeature(vf, f);
342 vfl.push_back(vf);
343 }
344 fs[omapper.idToIndex(p.getOutput())] = vfl;
345 }
346 }
347
348 static InputDomain
349 fromInputDomain(Vamp::Plugin::InputDomain d) {
350 switch(d) {
351 case Vamp::Plugin::TimeDomain:
352 return InputDomain::TIME_DOMAIN;
353 case Vamp::Plugin::FrequencyDomain:
354 return InputDomain::FREQUENCY_DOMAIN;
355 default:
356 throw std::logic_error("unexpected Vamp InputDomain enum value");
357 }
358 }
359
360 static Vamp::Plugin::InputDomain
361 toInputDomain(InputDomain d) {
362 switch(d) {
363 case InputDomain::TIME_DOMAIN:
364 return Vamp::Plugin::TimeDomain;
365 case InputDomain::FREQUENCY_DOMAIN:
366 return Vamp::Plugin::FrequencyDomain;
367 default:
368 throw std::logic_error("unexpected Capnp InputDomain enum value");
369 }
370 }
371
372 static void
373 buildExtractorStaticData(ExtractorStaticData::Builder &b,
374 const Vamp::HostExt::PluginStaticData &d) {
375
376 b.setKey(d.pluginKey);
377
378 auto basic = b.initBasic();
379 buildBasicDescriptor(basic, d.basic);
380
381 b.setMaker(d.maker);
382 b.setCopyright(d.copyright);
383 b.setVersion(d.pluginVersion);
384
385 auto clist = b.initCategory(d.category.size());
386 for (size_t i = 0; i < d.category.size(); ++i) {
387 clist.set(i, d.category[i]);
388 }
389
390 b.setMinChannelCount(d.minChannelCount);
391 b.setMaxChannelCount(d.maxChannelCount);
392
393 const auto &vparams = d.parameters;
394 auto plist = b.initParameters(vparams.size());
395 for (size_t i = 0; i < vparams.size(); ++i) {
396 auto pd = plist[i];
397 buildParameterDescriptor(pd, vparams[i]);
398 }
399
400 const auto &vprogs = d.programs;
401 auto pglist = b.initPrograms(vprogs.size());
402 for (size_t i = 0; i < vprogs.size(); ++i) {
403 pglist.set(i, vprogs[i]);
404 }
405
406 b.setInputDomain(fromInputDomain(d.inputDomain));
407
408 const auto &vouts = d.basicOutputInfo;
409 auto olist = b.initBasicOutputInfo(vouts.size());
410 for (size_t i = 0; i < vouts.size(); ++i) {
411 auto od = olist[i];
412 buildBasicDescriptor(od, vouts[i]);
413 }
414 }
415
416 static void
417 readExtractorStaticData(Vamp::HostExt::PluginStaticData &d,
418 const ExtractorStaticData::Reader &r) {
419
420 d.pluginKey = r.getKey();
421
422 readBasicDescriptor(d.basic, r.getBasic());
423
424 d.maker = r.getMaker();
425 d.copyright = r.getCopyright();
426 d.pluginVersion = r.getVersion();
427
428 d.category.clear();
429 auto cc = r.getCategory();
430 for (auto c: cc) {
431 d.category.push_back(c);
432 }
433
434 d.minChannelCount = r.getMinChannelCount();
435 d.maxChannelCount = r.getMaxChannelCount();
436
437 d.parameters.clear();
438 auto pp = r.getParameters();
439 for (auto p: pp) {
440 Vamp::Plugin::ParameterDescriptor pd;
441 readParameterDescriptor(pd, p);
442 d.parameters.push_back(pd);
443 }
444
445 d.programs.clear();
446 auto prp = r.getPrograms();
447 for (auto p: prp) {
448 d.programs.push_back(p);
449 }
450
451 d.inputDomain = toInputDomain(r.getInputDomain());
452
453 d.basicOutputInfo.clear();
454 auto oo = r.getBasicOutputInfo();
455 for (auto o: oo) {
456 Vamp::HostExt::PluginStaticData::Basic b;
457 readBasicDescriptor(b, o);
458 d.basicOutputInfo.push_back(b);
459 }
460 }
461
462 static void
463 buildConfiguration(Configuration::Builder &b,
464 const Vamp::HostExt::PluginConfiguration &c) {
465
466 const auto &vparams = c.parameterValues;
467 auto params = b.initParameterValues(vparams.size());
468 int i = 0;
469 for (const auto &pp : vparams) {
470 auto param = params[i++];
471 param.setParameter(pp.first);
472 param.setValue(pp.second);
473 }
474
475 b.setCurrentProgram(c.currentProgram);
476 b.setChannelCount(c.channelCount);
477 b.setStepSize(c.stepSize);
478 b.setBlockSize(c.blockSize);
479 }
480
481 static void
482 readConfiguration(Vamp::HostExt::PluginConfiguration &c,
483 const Configuration::Reader &r) {
484
485 auto pp = r.getParameterValues();
486 for (const auto &p: pp) {
487 c.parameterValues[p.getParameter()] = p.getValue();
488 }
489
490 c.currentProgram = r.getCurrentProgram();
491 c.channelCount = r.getChannelCount();
492 c.stepSize = r.getStepSize();
493 c.blockSize = r.getBlockSize();
494 }
495
496 static void
497 buildLoadRequest(LoadRequest::Builder &r,
498 const Vamp::HostExt::LoadRequest &req) {
499
500 r.setKey(req.pluginKey);
501 r.setInputSampleRate(req.inputSampleRate);
502
503 std::vector<AdapterFlag> flags;
504 if (req.adapterFlags & Vamp::HostExt::PluginLoader::ADAPT_INPUT_DOMAIN) {
505 flags.push_back(AdapterFlag::ADAPT_INPUT_DOMAIN);
506 }
507 if (req.adapterFlags & Vamp::HostExt::PluginLoader::ADAPT_CHANNEL_COUNT) {
508 flags.push_back(AdapterFlag::ADAPT_CHANNEL_COUNT);
509 }
510 if (req.adapterFlags & Vamp::HostExt::PluginLoader::ADAPT_BUFFER_SIZE) {
511 flags.push_back(AdapterFlag::ADAPT_BUFFER_SIZE);
512 }
513
514 auto f = r.initAdapterFlags(flags.size());
515 for (size_t i = 0; i < flags.size(); ++i) {
516 f.set(i, flags[i]);
517 }
518 }
519
520 static void
521 readLoadRequest(Vamp::HostExt::LoadRequest &req,
522 const LoadRequest::Reader &r) {
523
524 req.pluginKey = r.getKey();
525 req.inputSampleRate = r.getInputSampleRate();
526
527 int flags = 0;
528 auto aa = r.getAdapterFlags();
529 for (auto a: aa) {
530 if (a == AdapterFlag::ADAPT_INPUT_DOMAIN) {
531 flags |= Vamp::HostExt::PluginLoader::ADAPT_INPUT_DOMAIN;
532 }
533 if (a == AdapterFlag::ADAPT_CHANNEL_COUNT) {
534 flags |= Vamp::HostExt::PluginLoader::ADAPT_CHANNEL_COUNT;
535 }
536 if (a == AdapterFlag::ADAPT_BUFFER_SIZE) {
537 flags |= Vamp::HostExt::PluginLoader::ADAPT_BUFFER_SIZE;
538 }
539 }
540 req.adapterFlags = flags;
541 }
542
543 static void
544 buildLoadResponse(LoadResponse::Builder &b,
545 const Vamp::HostExt::LoadResponse &resp,
546 const PluginHandleMapper &pmapper) {
547
548 b.setHandle(pmapper.pluginToHandle(resp.plugin));
549 auto sd = b.initStaticData();
550 buildExtractorStaticData(sd, resp.staticData);
551 auto conf = b.initDefaultConfiguration();
552 buildConfiguration(conf, resp.defaultConfiguration);
553 }
554
555 static void
556 readLoadResponse(Vamp::HostExt::LoadResponse &resp,
557 const LoadResponse::Reader &r,
558 const PluginHandleMapper &pmapper) {
559
560 resp.plugin = pmapper.handleToPlugin(r.getHandle());
561 readExtractorStaticData(resp.staticData, r.getStaticData());
562 readConfiguration(resp.defaultConfiguration,
563 r.getDefaultConfiguration());
564 }
565
566 static void
567 buildConfigurationRequest(ConfigurationRequest::Builder &b,
568 const Vamp::HostExt::ConfigurationRequest &cr,
569 const PluginHandleMapper &pmapper) {
570
571 b.setHandle(pmapper.pluginToHandle(cr.plugin));
572 auto c = b.initConfiguration();
573 buildConfiguration(c, cr.configuration);
574 }
575
576 static void
577 readConfigurationRequest(Vamp::HostExt::ConfigurationRequest &cr,
578 const ConfigurationRequest::Reader &r,
579 const PluginHandleMapper &pmapper) {
580
581 auto h = r.getHandle();
582 cr.plugin = pmapper.handleToPlugin(h);
583 auto c = r.getConfiguration();
584 readConfiguration(cr.configuration, c);
585 }
586
587 static void
588 buildConfigurationResponse(ConfigurationResponse::Builder &b,
589 const Vamp::HostExt::ConfigurationResponse &cr,
590 const PluginHandleMapper &pmapper) {
591
592 b.setHandle(pmapper.pluginToHandle(cr.plugin));
593 auto olist = b.initOutputs(cr.outputs.size());
594 for (size_t i = 0; i < cr.outputs.size(); ++i) {
595 auto od = olist[i];
596 buildOutputDescriptor(od, cr.outputs[i]);
597 }
598 }
599
600 static void
601 readConfigurationResponse(Vamp::HostExt::ConfigurationResponse &cr,
602 const ConfigurationResponse::Reader &r,
603 const PluginHandleMapper &pmapper) {
604
605 cr.plugin = pmapper.handleToPlugin(r.getHandle());
606 cr.outputs.clear();
607 auto oo = r.getOutputs();
608 for (const auto &o: oo) {
609 Vamp::Plugin::OutputDescriptor desc;
610 readOutputDescriptor(desc, o);
611 cr.outputs.push_back(desc);
612 }
613 }
614
615 static void
616 buildProcessInput(ProcessInput::Builder &b,
617 Vamp::RealTime timestamp,
618 const std::vector<std::vector<float> > &buffers) {
619
620 auto t = b.initTimestamp();
621 buildRealTime(t, timestamp);
622 auto vv = b.initInputBuffers(buffers.size());
623 for (size_t ch = 0; ch < buffers.size(); ++ch) {
624 const int n = int(buffers[ch].size());
625 vv.init(ch, n);
626 auto v = vv[ch];
627 for (int i = 0; i < n; ++i) {
628 v.set(i, buffers[ch][i]);
629 }
630 }
631 }
632
633 static void
634 readProcessInput(Vamp::RealTime &timestamp,
635 std::vector<std::vector<float> > &buffers,
636 const ProcessInput::Reader &b) {
637
638 readRealTime(timestamp, b.getTimestamp());
639 buffers.clear();
640 auto vv = b.getInputBuffers();
641 for (const auto &v: vv) {
642 std::vector<float> buf;
643 for (auto x: v) {
644 buf.push_back(x);
645 }
646 buffers.push_back(buf);
647 }
648 }
649
650 static void
651 buildProcessRequest(ProcessRequest::Builder &b,
652 const Vamp::HostExt::ProcessRequest &pr,
653 const PluginHandleMapper &pmapper) {
654
655 b.setHandle(pmapper.pluginToHandle(pr.plugin));
656 auto input = b.initProcessInput();
657 buildProcessInput(input, pr.timestamp, pr.inputBuffers);
658 }
659
660 static void
661 readProcessRequest(Vamp::HostExt::ProcessRequest &pr,
662 const ProcessRequest::Reader &r,
663 const PluginHandleMapper &pmapper) {
664
665 auto h = r.getHandle();
666 pr.plugin = pmapper.handleToPlugin(h);
667 readProcessInput(pr.timestamp, pr.inputBuffers, r.getProcessInput());
668 }
669
670 static void
671 buildProcessResponse(ProcessResponse::Builder &b,
672 const Vamp::HostExt::ProcessResponse &pr,
673 const PluginHandleMapper &pmapper) {
674
675 b.setHandle(pmapper.pluginToHandle(pr.plugin));
676 auto f = b.initFeatures();
677 buildFeatureSet(f, pr.features,
678 *pmapper.pluginToOutputIdMapper(pr.plugin));
679 }
680
681 static void
682 readProcessResponse(Vamp::HostExt::ProcessResponse &pr,
683 const ProcessResponse::Reader &r,
684 const PluginHandleMapper &pmapper) {
685
686 auto h = r.getHandle();
687 pr.plugin = pmapper.handleToPlugin(h);
688 readFeatureSet(pr.features, r.getFeatures(),
689 *pmapper.handleToOutputIdMapper(r.getHandle()));
690 }
691
692 static void
693 buildFinishResponse(FinishResponse::Builder &b,
694 const Vamp::HostExt::ProcessResponse &pr,
695 const PluginHandleMapper &pmapper) {
696
697 b.setHandle(pmapper.pluginToHandle(pr.plugin));
698 auto f = b.initFeatures();
699 buildFeatureSet(f, pr.features,
700 *pmapper.pluginToOutputIdMapper(pr.plugin));
701 }
702
703 static void
704 readFinishResponse(Vamp::HostExt::ProcessResponse &pr,
705 const FinishResponse::Reader &r,
706 const PluginHandleMapper &pmapper) {
707
708 auto h = r.getHandle();
709 pr.plugin = pmapper.handleToPlugin(h);
710 readFeatureSet(pr.features, r.getFeatures(),
711 *pmapper.handleToOutputIdMapper(r.getHandle()));
712 }
713
714 static void
715 buildRpcRequest_List(RpcRequest::Builder &b) {
716 b.getRequest().initList();
717 }
718
719 static void
720 buildRpcResponse_List(RpcResponse::Builder &b,
721 const Vamp::HostExt::ListResponse &resp) {
722
723 auto r = b.getResponse().initList();
724 auto p = r.initAvailable(resp.available.size());
725 for (size_t i = 0; i < resp.available.size(); ++i) {
726 auto pd = p[i];
727 buildExtractorStaticData(pd, resp.available[i]);
728 }
729 }
730
731 static void
732 buildRpcRequest_Load(RpcRequest::Builder &b,
733 const Vamp::HostExt::LoadRequest &req) {
734 auto u = b.getRequest().initLoad();
735 buildLoadRequest(u, req);
736 }
737
738 static void
739 buildRpcResponse_Load(RpcResponse::Builder &b,
740 const Vamp::HostExt::LoadResponse &resp,
741 const PluginHandleMapper &pmapper) {
742
743 if (resp.plugin) {
744 auto u = b.getResponse().initLoad();
745 buildLoadResponse(u, resp, pmapper);
746 } else {
747 buildRpcResponse_Error(b, "Failed to load plugin", RRType::Load);
748 }
749 }
750
751 static void
752 buildRpcRequest_Configure(RpcRequest::Builder &b,
753 const Vamp::HostExt::ConfigurationRequest &cr,
754 const PluginHandleMapper &pmapper) {
755 auto u = b.getRequest().initConfigure();
756 buildConfigurationRequest(u, cr, pmapper);
757 }
758
759 static void
760 buildRpcResponse_Configure(RpcResponse::Builder &b,
761 const Vamp::HostExt::ConfigurationResponse &cr,
762 const PluginHandleMapper &pmapper) {
763
764 if (!cr.outputs.empty()) {
765 auto u = b.getResponse().initConfigure();
766 buildConfigurationResponse(u, cr, pmapper);
767 } else {
768 buildRpcResponse_Error(b, "Failed to configure plugin",
769 RRType::Configure);
770 }
771 }
772
773 static void
774 buildRpcRequest_Process(RpcRequest::Builder &b,
775 const Vamp::HostExt::ProcessRequest &pr,
776 const PluginHandleMapper &pmapper) {
777 auto u = b.getRequest().initProcess();
778 buildProcessRequest(u, pr, pmapper);
779 }
780
781 static void
782 buildRpcResponse_Process(RpcResponse::Builder &b,
783 const Vamp::HostExt::ProcessResponse &pr,
784 const PluginHandleMapper &pmapper) {
785
786 auto u = b.getResponse().initProcess();
787 buildProcessResponse(u, pr, pmapper);
788 }
789
790 static void
791 buildRpcRequest_Finish(RpcRequest::Builder &b,
792 const Vamp::HostExt::FinishRequest &req,
793 const PluginHandleMapper &pmapper) {
794
795 auto u = b.getRequest().initFinish();
796 u.setHandle(pmapper.pluginToHandle(req.plugin));
797 }
798
799 static void
800 buildRpcResponse_Finish(RpcResponse::Builder &b,
801 const Vamp::HostExt::ProcessResponse &pr,
802 const PluginHandleMapper &pmapper) {
803
804 auto u = b.getResponse().initFinish();
805 buildFinishResponse(u, pr, pmapper);
806 }
807
808 static void
809 buildRpcResponse_Error(RpcResponse::Builder &b,
810 const std::string &errorText,
811 RRType responseType)
812 {
813 std::string type;
814
815 auto e = b.getResponse().initError();
816
817 if (responseType == RRType::List) {
818 type = "list";
819 } else if (responseType == RRType::Load) {
820 type = "load";
821 } else if (responseType == RRType::Configure) {
822 type = "configure";
823 } else if (responseType == RRType::Process) {
824 type = "process";
825 } else if (responseType == RRType::Finish) {
826 type = "finish";
827 } else {
828 type = "invalid";
829 }
830
831 e.setCode(0);
832 e.setMessage(std::string("error in ") + type + " request: " + errorText);
833 }
834
835 static void
836 buildRpcResponse_Exception(RpcResponse::Builder &b,
837 const std::exception &e,
838 RRType responseType)
839 {
840 return buildRpcResponse_Error(b, e.what(), responseType);
841 }
842
843 static RRType
844 getRequestResponseType(const RpcRequest::Reader &r) {
845 switch (r.getRequest().which()) {
846 case RpcRequest::Request::Which::LIST:
847 return RRType::List;
848 case RpcRequest::Request::Which::LOAD:
849 return RRType::Load;
850 case RpcRequest::Request::Which::CONFIGURE:
851 return RRType::Configure;
852 case RpcRequest::Request::Which::PROCESS:
853 return RRType::Process;
854 case RpcRequest::Request::Which::FINISH:
855 return RRType::Finish;
856 }
857 return RRType::NotValid;
858 }
859
860 static RRType
861 getRequestResponseType(const RpcResponse::Reader &r) {
862 switch (r.getResponse().which()) {
863 case RpcResponse::Response::Which::ERROR:
864 return RRType::NotValid; //!!! or error type? test this
865 case RpcResponse::Response::Which::LIST:
866 return RRType::List;
867 case RpcResponse::Response::Which::LOAD:
868 return RRType::Load;
869 case RpcResponse::Response::Which::CONFIGURE:
870 return RRType::Configure;
871 case RpcResponse::Response::Which::PROCESS:
872 return RRType::Process;
873 case RpcResponse::Response::Which::FINISH:
874 return RRType::Finish;
875 }
876 return RRType::NotValid;
877 }
878
879 static void
880 readRpcResponse_Error(int &code,
881 std::string &message,
882 const RpcResponse::Reader &r) {
883 if (getRequestResponseType(r) != RRType::NotValid) {
884 throw std::logic_error("not an error response");
885 }
886 code = r.getResponse().getError().getCode();
887 message = r.getResponse().getError().getMessage();
888 }
889
890 static void
891 readRpcRequest_List(const RpcRequest::Reader &r) {
892 if (getRequestResponseType(r) != RRType::List) {
893 throw std::logic_error("not a list request");
894 }
895 }
896
897 static void
898 readRpcResponse_List(Vamp::HostExt::ListResponse &resp,
899 const RpcResponse::Reader &r) {
900 if (getRequestResponseType(r) != RRType::List) {
901 throw std::logic_error("not a list response");
902 }
903 resp.available.clear();
904 auto pp = r.getResponse().getList().getAvailable();
905 for (const auto &p: pp) {
906 Vamp::HostExt::PluginStaticData psd;
907 readExtractorStaticData(psd, p);
908 resp.available.push_back(psd);
909 }
910 }
911
912 static void
913 readRpcRequest_Load(Vamp::HostExt::LoadRequest &req,
914 const RpcRequest::Reader &r) {
915 if (getRequestResponseType(r) != RRType::Load) {
916 throw std::logic_error("not a load request");
917 }
918 readLoadRequest(req, r.getRequest().getLoad());
919 }
920
921 static void
922 readRpcResponse_Load(Vamp::HostExt::LoadResponse &resp,
923 const RpcResponse::Reader &r,
924 const PluginHandleMapper &pmapper) {
925 if (getRequestResponseType(r) != RRType::Load) {
926 throw std::logic_error("not a load response");
927 }
928 resp = {};
929 readLoadResponse(resp, r.getResponse().getLoad(), pmapper);
930 }
931
932 static void
933 readRpcRequest_Configure(Vamp::HostExt::ConfigurationRequest &req,
934 const RpcRequest::Reader &r,
935 const PluginHandleMapper &pmapper) {
936 if (getRequestResponseType(r) != RRType::Configure) {
937 throw std::logic_error("not a configuration request");
938 }
939 readConfigurationRequest(req, r.getRequest().getConfigure(), pmapper);
940 }
941
942 static void
943 readRpcResponse_Configure(Vamp::HostExt::ConfigurationResponse &resp,
944 const RpcResponse::Reader &r,
945 const PluginHandleMapper &pmapper) {
946 if (getRequestResponseType(r) != RRType::Configure) {
947 throw std::logic_error("not a configuration response");
948 }
949 resp = {};
950 readConfigurationResponse(resp,
951 r.getResponse().getConfigure(),
952 pmapper);
953 }
954
955 static void
956 readRpcRequest_Process(Vamp::HostExt::ProcessRequest &req,
957 const RpcRequest::Reader &r,
958 const PluginHandleMapper &pmapper) {
959 if (getRequestResponseType(r) != RRType::Process) {
960 throw std::logic_error("not a process request");
961 }
962 readProcessRequest(req, r.getRequest().getProcess(), pmapper);
963 }
964
965 static void
966 readRpcResponse_Process(Vamp::HostExt::ProcessResponse &resp,
967 const RpcResponse::Reader &r,
968 const PluginHandleMapper &pmapper) {
969 if (getRequestResponseType(r) != RRType::Process) {
970 throw std::logic_error("not a process response");
971 }
972 resp = {};
973 readProcessResponse(resp, r.getResponse().getProcess(), pmapper);
974 }
975
976 static void
977 readRpcRequest_Finish(Vamp::HostExt::FinishRequest &req,
978 const RpcRequest::Reader &r,
979 const PluginHandleMapper &pmapper) {
980 if (getRequestResponseType(r) != RRType::Finish) {
981 throw std::logic_error("not a finish request");
982 }
983 req.plugin = pmapper.handleToPlugin
984 (r.getRequest().getFinish().getHandle());
985 }
986
987 static void
988 readRpcResponse_Finish(Vamp::HostExt::ProcessResponse &resp,
989 const RpcResponse::Reader &r,
990 const PluginHandleMapper &pmapper) {
991 if (getRequestResponseType(r) != RRType::Finish) {
992 throw std::logic_error("not a finish response");
993 }
994 resp = {};
995 readFinishResponse(resp, r.getResponse().getFinish(), pmapper);
996 }
997 };
998
999 }
1000
1001