Mercurial > hg > piper-cpp
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/capnproto/VampnProto.h Fri May 13 13:48:59 2016 +0100 @@ -0,0 +1,475 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +#include "vamp.capnp.h" + +#include <capnp/message.h> +#include <capnp/serialize-packed.h> + +#include <vamp-hostsdk/Plugin.h> +#include <vamp-hostsdk/PluginLoader.h> +#include <vamp-hostsdk/PluginStaticData.h> + +namespace vampipe +{ + +/** + * Convert the structures laid out in the Vamp SDK classes into Cap'n + * Proto structures. + * + * At least some of this will be necessary for any implementation that + * is using the C++ Vamp SDK to provide its reference structures. An + * implementation could alternatively use the Cap'n Proto structures + * directly, and interact with Vamp plugins using the Vamp C API, + * without using the C++ Vamp SDK classes at all. + */ + +class VampSDKConverter +{ +public: + typedef ::capnp::MallocMessageBuilder MsgBuilder; + + template <typename T, typename B> + static void buildBasicDescriptor(B &basic, const T &t) { + basic.setIdentifier(t.identifier); + basic.setName(t.name); + basic.setDescription(t.description); + } + + template <typename T, typename B> + static void readBasicDescriptor(T &t, const B &basic) { + t.identifier = basic.getIdentifier(); + t.name = basic.getName(); + t.description = basic.getDescription(); + } + + template <typename T, typename M> + static void buildValueExtents(M &m, const T &t) { + m.setMinValue(t.minValue); + m.setMaxValue(t.maxValue); + } + + template <typename T, typename M> + static void readValueExtents(T &t, const M &m) { + t.minValue = m.getMinValue(); + t.maxValue = m.getMaxValue(); + } + + static void buildRealTime(RealTime::Builder &b, const Vamp::RealTime &t) { + b.setSec(t.sec); + b.setNsec(t.nsec); + } + + static void readRealTime(Vamp::RealTime &t, const RealTime::Reader &r) { + t.sec = r.getSec(); + t.nsec = r.getNsec(); + } + + static SampleType + fromSampleType(Vamp::Plugin::OutputDescriptor::SampleType t) { + switch (t) { + case Vamp::Plugin::OutputDescriptor::OneSamplePerStep: + return SampleType::ONE_SAMPLE_PER_STEP; + case Vamp::Plugin::OutputDescriptor::FixedSampleRate: + return SampleType::FIXED_SAMPLE_RATE; + case Vamp::Plugin::OutputDescriptor::VariableSampleRate: + return SampleType::VARIABLE_SAMPLE_RATE; + } + throw std::logic_error("unexpected Vamp SampleType enum value"); + } + + static Vamp::Plugin::OutputDescriptor::SampleType + toSampleType(SampleType t) { + switch (t) { + case SampleType::ONE_SAMPLE_PER_STEP: + return Vamp::Plugin::OutputDescriptor::OneSamplePerStep; + case SampleType::FIXED_SAMPLE_RATE: + return Vamp::Plugin::OutputDescriptor::FixedSampleRate; + case SampleType::VARIABLE_SAMPLE_RATE: + return Vamp::Plugin::OutputDescriptor::VariableSampleRate; + } + throw std::logic_error("unexpected Capnp SampleType enum value"); + } + + static void + buildOutputDescriptor(OutputDescriptor::Builder &b, + const Vamp::Plugin::OutputDescriptor &od) { + + auto basic = b.initBasic(); + buildBasicDescriptor(basic, od); + + b.setUnit(od.unit); + + b.setSampleType(fromSampleType(od.sampleType)); + b.setSampleRate(od.sampleRate); + b.setHasDuration(od.hasDuration); + + b.setHasFixedBinCount(od.hasFixedBinCount); + if (od.hasFixedBinCount) { + b.setBinCount(od.binCount); + if (od.binNames.size() > 0) { + auto binNames = b.initBinNames(od.binNames.size()); + for (size_t i = 0; i < od.binNames.size(); ++i) { + binNames.set(i, od.binNames[i]); + } + } + } + + b.setHasKnownExtents(od.hasKnownExtents); + if (od.hasKnownExtents) { + buildValueExtents(b, od); + } + + b.setIsQuantized(od.isQuantized); + if (od.isQuantized) { + b.setQuantizeStep(od.quantizeStep); + } + } + + static void + readOutputDescriptor(Vamp::Plugin::OutputDescriptor &od, + const OutputDescriptor::Reader &r) { + + readBasicDescriptor(od, r.getBasic()); + + od.unit = r.getUnit(); + + od.sampleType = toSampleType(r.getSampleType()); + od.sampleRate = r.getSampleRate(); + od.hasDuration = r.getHasDuration(); + + od.hasFixedBinCount = r.getHasFixedBinCount(); + if (od.hasFixedBinCount) { + od.binCount = r.getBinCount(); + for (const auto &n: r.getBinNames()) { + od.binNames.push_back(n); + } + } + + od.hasKnownExtents = r.getHasKnownExtents(); + if (od.hasKnownExtents) { + readValueExtents(od, r); + } + + od.isQuantized = r.getIsQuantized(); + if (od.isQuantized) { + od.quantizeStep = r.getQuantizeStep(); + } + } + + static void + buildParameterDescriptor(ParameterDescriptor::Builder &b, + const Vamp::Plugin::ParameterDescriptor &pd) { + + auto basic = b.initBasic(); + buildBasicDescriptor(basic, pd); + + b.setUnit(pd.unit); + + buildValueExtents(b, pd); + + b.setDefaultValue(pd.defaultValue); + + b.setIsQuantized(pd.isQuantized); + if (pd.isQuantized) { + b.setQuantizeStep(pd.quantizeStep); + } + + if (pd.valueNames.size() > 0) { + auto valueNames = b.initValueNames(pd.valueNames.size()); + for (size_t i = 0; i < pd.valueNames.size(); ++i) { + valueNames.set(i, pd.valueNames[i]); + } + } + } + + static void + readParameterDescriptor(Vamp::Plugin::ParameterDescriptor &pd, + const ParameterDescriptor::Reader &r) { + + readBasicDescriptor(pd, r.getBasic()); + + pd.unit = r.getUnit(); + + readValueExtents(pd, r); + + pd.defaultValue = r.getDefaultValue(); + + pd.isQuantized = r.getIsQuantized(); + if (pd.isQuantized) { + pd.quantizeStep = r.getQuantizeStep(); + } + + for (const auto &n: r.getValueNames()) { + pd.valueNames.push_back(n); + } + } + + static void + buildFeature(Feature::Builder &b, + const Vamp::Plugin::Feature &f) { + + b.setHasTimestamp(f.hasTimestamp); + if (f.hasTimestamp) { + auto timestamp = b.initTimestamp(); + buildRealTime(timestamp, f.timestamp); + } + + b.setHasDuration(f.hasDuration); + if (f.hasDuration) { + auto duration = b.initDuration(); + buildRealTime(duration, f.duration); + } + + b.setLabel(f.label); + + if (f.values.size() > 0) { + auto values = b.initValues(f.values.size()); + for (size_t i = 0; i < f.values.size(); ++i) { + values.set(i, f.values[i]); + } + } + } + + static void + readFeature(Vamp::Plugin::Feature &f, + const Feature::Reader &r) { + + f.hasTimestamp = r.getHasTimestamp(); + if (f.hasTimestamp) { + readRealTime(f.timestamp, r.getTimestamp()); + } + + f.hasDuration = r.getHasDuration(); + if (f.hasDuration) { + readRealTime(f.duration, r.getDuration()); + } + + f.label = r.getLabel(); + + for (auto v: r.getValues()) { + f.values.push_back(v); + } + } + + static void + buildFeatureSet(FeatureSet::Builder &b, + const Vamp::Plugin::FeatureSet &fs) { + + auto featureset = b.initFeaturePairs(fs.size()); + int ix = 0; + for (const auto &fsi : fs) { + auto fspair = featureset[ix]; + fspair.setOutput(fsi.first); + auto featurelist = fspair.initFeatures(fsi.second.size()); + for (size_t j = 0; j < fsi.second.size(); ++j) { + auto feature = featurelist[j]; + buildFeature(feature, fsi.second[j]); + } + ++ix; + } + } + + static void + readFeatureSet(Vamp::Plugin::FeatureSet &fs, + const FeatureSet::Reader &r) { + + for (const auto &p: r.getFeaturePairs()) { + Vamp::Plugin::FeatureList vfl; + for (const auto &f: p.getFeatures()) { + Vamp::Plugin::Feature vf; + readFeature(vf, f); + vfl.push_back(vf); + } + fs[p.getOutput()] = vfl; + } + } + + static InputDomain + fromInputDomain(Vamp::Plugin::InputDomain d) { + switch(d) { + case Vamp::Plugin::TimeDomain: + return InputDomain::TIME_DOMAIN; + case Vamp::Plugin::FrequencyDomain: + return InputDomain::FREQUENCY_DOMAIN; + default: + throw std::logic_error("unexpected Vamp InputDomain enum value"); + } + } + + static Vamp::Plugin::InputDomain + toInputDomain(InputDomain d) { + switch(d) { + case InputDomain::TIME_DOMAIN: + return Vamp::Plugin::TimeDomain; + case InputDomain::FREQUENCY_DOMAIN: + return Vamp::Plugin::FrequencyDomain; + default: + throw std::logic_error("unexpected Capnp InputDomain enum value"); + } + } + + static void + buildPluginStaticData(PluginStaticData::Builder &b, + const Vamp::HostExt::PluginStaticData &d) { + + b.setPluginKey(d.pluginKey); + + auto basic = b.initBasic(); + buildBasicDescriptor(basic, d.basic); + + b.setMaker(d.maker); + b.setCopyright(d.copyright); + b.setPluginVersion(d.pluginVersion); + + auto clist = b.initCategory(d.category.size()); + for (size_t i = 0; i < d.category.size(); ++i) { + clist.set(i, d.category[i]); + } + + b.setMinChannelCount(d.minChannelCount); + b.setMaxChannelCount(d.maxChannelCount); + + const auto &vparams = d.parameters; + auto plist = b.initParameters(vparams.size()); + for (size_t i = 0; i < vparams.size(); ++i) { + auto pd = plist[i]; + buildParameterDescriptor(pd, vparams[i]); + } + + const auto &vprogs = d.programs; + auto pglist = b.initPrograms(vprogs.size()); + for (size_t i = 0; i < vprogs.size(); ++i) { + pglist.set(i, vprogs[i]); + } + + b.setInputDomain(fromInputDomain(d.inputDomain)); + + const auto &vouts = d.basicOutputInfo; + auto olist = b.initBasicOutputInfo(vouts.size()); + for (size_t i = 0; i < vouts.size(); ++i) { + auto od = olist[i]; + buildBasicDescriptor(od, vouts[i]); + } + } + + static void + readPluginStaticData(Vamp::HostExt::PluginStaticData &d, + const PluginStaticData::Reader &r) { + + d.pluginKey = r.getPluginKey(); + + readBasicDescriptor(d.basic, r.getBasic()); + + d.maker = r.getMaker(); + d.copyright = r.getCopyright(); + d.pluginVersion = r.getPluginVersion(); + + for (auto c: r.getCategory()) { + d.category.push_back(c); + } + + d.minChannelCount = r.getMinChannelCount(); + d.maxChannelCount = r.getMaxChannelCount(); + + for (auto p: r.getParameters()) { + Vamp::Plugin::ParameterDescriptor pd; + readParameterDescriptor(pd, p); + d.parameters.push_back(pd); + } + + for (auto p: r.getPrograms()) { + d.programs.push_back(p); + } + + d.inputDomain = toInputDomain(r.getInputDomain()); + + for (auto o: r.getBasicOutputInfo()) { + Vamp::HostExt::PluginStaticData::Basic b; + readBasicDescriptor(b, o); + d.basicOutputInfo.push_back(b); + } + } + + static void + buildPluginConfiguration(PluginConfiguration::Builder &b, + const Vamp::HostExt::PluginConfiguration &c) { + + const auto &vparams = c.parameterValues; + auto params = b.initParameterValues(vparams.size()); + int i = 0; + for (const auto &pp : vparams) { + auto param = params[i++]; + param.setParameter(pp.first); + param.setValue(pp.second); + } + + b.setCurrentProgram(c.currentProgram); + b.setChannelCount(c.channelCount); + b.setStepSize(c.stepSize); + b.setBlockSize(c.blockSize); + } + + static void + readPluginConfiguration(Vamp::HostExt::PluginConfiguration &c, + const PluginConfiguration::Reader &r) { + + for (const auto &pp: r.getParameterValues()) { + c.parameterValues[pp.getParameter()] = pp.getValue(); + } + + c.currentProgram = r.getCurrentProgram(); + c.channelCount = r.getChannelCount(); + c.stepSize = r.getStepSize(); + c.blockSize = r.getBlockSize(); + } + + static void + buildLoadRequest(LoadRequest::Builder &r, + const Vamp::HostExt::LoadRequest &req) { + + r.setPluginKey(req.pluginKey); + r.setInputSampleRate(req.inputSampleRate); + + std::vector<AdapterFlag> flags; + if (req.adapterFlags & Vamp::HostExt::PluginLoader::ADAPT_INPUT_DOMAIN) { + flags.push_back(AdapterFlag::ADAPT_INPUT_DOMAIN); + } + if (req.adapterFlags & Vamp::HostExt::PluginLoader::ADAPT_CHANNEL_COUNT) { + flags.push_back(AdapterFlag::ADAPT_CHANNEL_COUNT); + } + if (req.adapterFlags & Vamp::HostExt::PluginLoader::ADAPT_BUFFER_SIZE) { + flags.push_back(AdapterFlag::ADAPT_BUFFER_SIZE); + } + + auto f = r.initAdapterFlags(flags.size()); + for (size_t i = 0; i < flags.size(); ++i) { + f.set(i, flags[i]); + } + } + + static void + readLoadRequest(Vamp::HostExt::LoadRequest &req, + const LoadRequest::Reader &r) { + + req.pluginKey = r.getPluginKey(); + req.inputSampleRate = r.getInputSampleRate(); + + int flags = 0; + for (const auto &a: r.getAdapterFlags()) { + if (a == AdapterFlag::ADAPT_INPUT_DOMAIN) { + flags |= Vamp::HostExt::PluginLoader::ADAPT_INPUT_DOMAIN; + } + if (a == AdapterFlag::ADAPT_CHANNEL_COUNT) { + flags |= Vamp::HostExt::PluginLoader::ADAPT_CHANNEL_COUNT; + } + if (a == AdapterFlag::ADAPT_BUFFER_SIZE) { + flags |= Vamp::HostExt::PluginLoader::ADAPT_BUFFER_SIZE; + } + } + req.adapterFlags = flags; + } +}; + +} + +