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;
+    }
+};
+
+}
+
+