annotate capnproto/VampnProto.h @ 10:c8451896c40e

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