Mercurial > hg > piper-cpp
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 ×tamp, | |
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 |