changeset 96:215c9fb6b7a4

Rename to CapnpRRClient (request-response, as opposed to individual RPC calls)
author Chris Cannam <c.cannam@qmul.ac.uk>
date Thu, 13 Oct 2016 17:00:06 +0100
parents b6ac26b72b59
children 427c4c725085
files vamp-client/CapnpClient.h vamp-client/CapnpRRClient.h vamp-client/Makefile vamp-client/client.cpp vamp-client/client.pro
diffstat 5 files changed, 387 insertions(+), 371 deletions(-) [+]
line wrap: on
line diff
--- a/vamp-client/CapnpClient.h	Thu Oct 13 14:31:10 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-
-#ifndef PIPER_CAPNP_CLIENT_H
-#define PIPER_CAPNP_CLIENT_H
-
-#include "Loader.h"
-#include "PluginClient.h"
-#include "PluginStub.h"
-#include "SynchronousTransport.h"
-
-#include "vamp-support/AssignedPluginHandleMapper.h"
-#include "vamp-capnp/VampnProto.h"
-
-#include <capnp/serialize.h>
-
-namespace piper {
-namespace vampclient {
-
-class CapnpClient : public PluginClient,
-                    public Loader
-{
-    // unsigned to avoid undefined behaviour on possible wrap
-    typedef uint32_t ReqId;
-
-    class CompletenessChecker : public MessageCompletenessChecker {
-    public:
-        bool isComplete(const std::vector<char> &message) const override {
-            auto karr = toKJArray(message);
-            size_t words = karr.size();
-            size_t expected = capnp::expectedSizeInWordsFromPrefix(karr);
-            if (words > expected) {
-                std::cerr << "WARNING: obtained more data than expected ("
-                          << words << " " << sizeof(capnp::word)
-                          << "-byte words, expected "
-                          << expected << ")" << std::endl;
-            }
-            return words >= expected;
-        }
-    };
-    
-public:
-    CapnpClient(SynchronousTransport *transport) : //!!! ownership? shared ptr?
-        m_transport(transport),
-        m_completenessChecker(new CompletenessChecker) {
-        transport->setCompletenessChecker(m_completenessChecker);
-    }
-
-    ~CapnpClient() {
-        delete m_completenessChecker;
-    }
-
-    //!!! obviously, factor out all repetitive guff
-
-    //!!! list and load are supposed to be called by application code,
-    //!!! but the rest are only supposed to be called by the plugin --
-    //!!! sort out the api here
-
-    // Loader methods:
-
-    Vamp::HostExt::ListResponse
-    listPluginData() override {
-
-        if (!m_transport->isOK()) {
-            throw std::runtime_error("Piper server failed to start");
-        }
-
-        capnp::MallocMessageBuilder message;
-        RpcRequest::Builder builder = message.initRoot<RpcRequest>();
-        VampnProto::buildRpcRequest_List(builder);
-        ReqId id = getId();
-        builder.getId().setNumber(id);
-
-        //!!! pure boilerplate:
-        auto arr = capnp::messageToFlatArray(message);
-        auto responseBuffer = m_transport->call(arr.asChars().begin(),
-                                                arr.asChars().size());
-	auto karr = toKJArray(responseBuffer);
-        capnp::FlatArrayMessageReader responseMessage(karr);
-        RpcResponse::Reader reader = responseMessage.getRoot<RpcResponse>();
-
-        checkResponseType(reader, RpcResponse::Response::Which::LIST, id);
-
-        Vamp::HostExt::ListResponse lr;
-        VampnProto::readListResponse(lr, reader.getResponse().getList());
-        return lr;
-    }
-    
-    Vamp::HostExt::LoadResponse
-    loadPlugin(const Vamp::HostExt::LoadRequest &req) override {
-
-        if (!m_transport->isOK()) {
-            throw std::runtime_error("Piper server failed to start");
-        }
-
-        Vamp::HostExt::LoadResponse resp;
-        PluginHandleMapper::Handle handle = serverLoad(req.pluginKey,
-                                                       req.inputSampleRate,
-                                                       req.adapterFlags,
-                                                       resp.staticData,
-                                                       resp.defaultConfiguration);
-
-        Vamp::Plugin *plugin = new PluginStub(this,
-                                              req.pluginKey,
-                                              req.inputSampleRate,
-                                              req.adapterFlags,
-                                              resp.staticData,
-                                              resp.defaultConfiguration);
-
-        m_mapper.addPlugin(handle, plugin);
-
-        resp.plugin = plugin;
-        return resp;
-    }
-
-    // PluginClient methods:
-    
-    virtual
-    Vamp::Plugin::OutputList
-    configure(PluginStub *plugin,
-              Vamp::HostExt::PluginConfiguration config) override {
-
-        if (!m_transport->isOK()) {
-            throw std::runtime_error("Piper server failed to start");
-        }
-
-        Vamp::HostExt::ConfigurationRequest request;
-        request.plugin = plugin;
-        request.configuration = config;
-
-        capnp::MallocMessageBuilder message;
-        RpcRequest::Builder builder = message.initRoot<RpcRequest>();
-
-        VampnProto::buildRpcRequest_Configure(builder, request, m_mapper);
-        ReqId id = getId();
-        builder.getId().setNumber(id);
-        
-        auto arr = capnp::messageToFlatArray(message);
-        auto responseBuffer = m_transport->call(arr.asChars().begin(),
-                                                arr.asChars().size());
-	auto karr = toKJArray(responseBuffer);
-        capnp::FlatArrayMessageReader responseMessage(karr);
-        RpcResponse::Reader reader = responseMessage.getRoot<RpcResponse>();
-
-        //!!! handle (explicit) error case
-
-        checkResponseType(reader, RpcResponse::Response::Which::CONFIGURE, id);
-
-        Vamp::HostExt::ConfigurationResponse cr;
-        VampnProto::readConfigurationResponse(cr,
-                                              reader.getResponse().getConfigure(),
-                                              m_mapper);
-
-        return cr.outputs;
-    };
-    
-    virtual
-    Vamp::Plugin::FeatureSet
-    process(PluginStub *plugin,
-            std::vector<std::vector<float> > inputBuffers,
-            Vamp::RealTime timestamp) override {
-
-        if (!m_transport->isOK()) {
-            throw std::runtime_error("Piper server failed to start");
-        }
-
-        Vamp::HostExt::ProcessRequest request;
-        request.plugin = plugin;
-        request.inputBuffers = inputBuffers;
-        request.timestamp = timestamp;
-        
-        capnp::MallocMessageBuilder message;
-        RpcRequest::Builder builder = message.initRoot<RpcRequest>();
-
-        VampnProto::buildRpcRequest_Process(builder, request, m_mapper);
-        ReqId id = getId();
-        builder.getId().setNumber(id);
-        
-        auto arr = capnp::messageToFlatArray(message);
-        auto responseBuffer = m_transport->call(arr.asChars().begin(),
-                                                arr.asChars().size());
-	auto karr = toKJArray(responseBuffer);
-        capnp::FlatArrayMessageReader responseMessage(karr);
-        RpcResponse::Reader reader = responseMessage.getRoot<RpcResponse>();
-
-        //!!! handle (explicit) error case
-
-        checkResponseType(reader, RpcResponse::Response::Which::PROCESS, id);
-
-        Vamp::HostExt::ProcessResponse pr;
-        VampnProto::readProcessResponse(pr,
-                                        reader.getResponse().getProcess(),
-                                        m_mapper);
-
-        return pr.features;
-    }
-
-    virtual Vamp::Plugin::FeatureSet
-    finish(PluginStub *plugin) override {
-
-        if (!m_transport->isOK()) {
-            throw std::runtime_error("Piper server failed to start");
-        }
-
-        Vamp::HostExt::FinishRequest request;
-        request.plugin = plugin;
-        
-        capnp::MallocMessageBuilder message;
-        RpcRequest::Builder builder = message.initRoot<RpcRequest>();
-
-        VampnProto::buildRpcRequest_Finish(builder, request, m_mapper);
-        ReqId id = getId();
-        builder.getId().setNumber(id);
-        
-        auto arr = capnp::messageToFlatArray(message);
-        auto responseBuffer = m_transport->call(arr.asChars().begin(),
-                                                arr.asChars().size());
-	auto karr = toKJArray(responseBuffer);
-        capnp::FlatArrayMessageReader responseMessage(karr);
-        RpcResponse::Reader reader = responseMessage.getRoot<RpcResponse>();
-
-        //!!! handle (explicit) error case
-
-        checkResponseType(reader, RpcResponse::Response::Which::FINISH, id);
-
-        Vamp::HostExt::ProcessResponse pr;
-        VampnProto::readFinishResponse(pr,
-                                       reader.getResponse().getFinish(),
-                                       m_mapper);
-
-        m_mapper.removePlugin(m_mapper.pluginToHandle(plugin));
-
-	// Don't delete the plugin. It's the plugin that is supposed
-	// to be calling us here
-        
-        return pr.features;
-    }
-
-    virtual void
-    reset(PluginStub *plugin,
-          Vamp::HostExt::PluginConfiguration config) override {
-
-        // Reload the plugin on the server side, and configure it as requested
-        
-        if (!m_transport->isOK()) {
-            throw std::runtime_error("Piper server failed to start");
-        }
-
-        if (m_mapper.havePlugin(plugin)) {
-            (void)finish(plugin); // server-side unload
-        }
-
-        Vamp::HostExt::PluginStaticData psd;
-        Vamp::HostExt::PluginConfiguration defaultConfig;
-        PluginHandleMapper::Handle handle =
-            serverLoad(plugin->getPluginKey(),
-                       plugin->getInputSampleRate(),
-                       plugin->getAdapterFlags(),
-                       psd, defaultConfig);
-
-        m_mapper.addPlugin(handle, plugin);
-
-        (void)configure(plugin, config);
-    }
-    
-private:
-    AssignedPluginHandleMapper m_mapper;
-    ReqId getId() {
-        //!!! todo: mutex
-        static ReqId m_nextId = 0;
-        return m_nextId++;
-    }
-
-    static
-    kj::Array<capnp::word>
-    toKJArray(const std::vector<char> &buffer) {
-	// We could do this whole thing with fewer copies, but let's
-	// see whether it matters first
-        size_t wordSize = sizeof(capnp::word);
-	size_t words = buffer.size() / wordSize;
-	kj::Array<capnp::word> karr(kj::heapArray<capnp::word>(words));
-	memcpy(karr.begin(), buffer.data(), words * wordSize);
-	return karr;
-    }
-
-    void
-    checkResponseType(const RpcResponse::Reader &r,
-                      RpcResponse::Response::Which type,
-                      ReqId id) {
-        
-        if (r.getResponse().which() != type) {
-            throw std::runtime_error("Wrong response type");
-        }
-        if (ReqId(r.getId().getNumber()) != id) {
-            throw std::runtime_error("Wrong response id");
-        }
-    }
-    
-    PluginHandleMapper::Handle
-    serverLoad(std::string key, float inputSampleRate, int adapterFlags,
-               Vamp::HostExt::PluginStaticData &psd,
-               Vamp::HostExt::PluginConfiguration &defaultConfig) {
-
-        Vamp::HostExt::LoadRequest request;
-        request.pluginKey = key;
-        request.inputSampleRate = inputSampleRate;
-        request.adapterFlags = adapterFlags;
-
-        capnp::MallocMessageBuilder message;
-        RpcRequest::Builder builder = message.initRoot<RpcRequest>();
-
-        VampnProto::buildRpcRequest_Load(builder, request);
-        ReqId id = getId();
-        builder.getId().setNumber(id);
-
-        auto arr = capnp::messageToFlatArray(message);
-
-        auto responseBuffer = m_transport->call(arr.asChars().begin(),
-                                                arr.asChars().size());
-        
-        //!!! ... --> will also need some way to kill this process
-        //!!! (from another thread)
-
-	auto karr = toKJArray(responseBuffer);
-        capnp::FlatArrayMessageReader responseMessage(karr);
-        RpcResponse::Reader reader = responseMessage.getRoot<RpcResponse>();
-
-        //!!! handle (explicit) error case
-
-        checkResponseType(reader, RpcResponse::Response::Which::LOAD, id);
-        
-        const LoadResponse::Reader &lr = reader.getResponse().getLoad();
-        VampnProto::readExtractorStaticData(psd, lr.getStaticData());
-        VampnProto::readConfiguration(defaultConfig, lr.getDefaultConfiguration());
-        return lr.getHandle();
-    };     
-
-private:
-    SynchronousTransport *m_transport; //!!! I don't own this, but should I?
-    CompletenessChecker *m_completenessChecker; // I own this
-};
-
-}
-}
-
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vamp-client/CapnpRRClient.h	Thu Oct 13 17:00:06 2016 +0100
@@ -0,0 +1,338 @@
+
+#ifndef PIPER_CAPNP_CLIENT_H
+#define PIPER_CAPNP_CLIENT_H
+
+#include "Loader.h"
+#include "PluginClient.h"
+#include "PluginStub.h"
+#include "SynchronousTransport.h"
+
+#include "vamp-support/AssignedPluginHandleMapper.h"
+#include "vamp-capnp/VampnProto.h"
+
+#include <capnp/serialize.h>
+
+namespace piper {
+namespace vampclient {
+
+class CapnpRRClient : public PluginClient,
+                    public Loader
+{
+    // unsigned to avoid undefined behaviour on possible wrap
+    typedef uint32_t ReqId;
+
+    class CompletenessChecker : public MessageCompletenessChecker {
+    public:
+        bool isComplete(const std::vector<char> &message) const override {
+            auto karr = toKJArray(message);
+            size_t words = karr.size();
+            size_t expected = capnp::expectedSizeInWordsFromPrefix(karr);
+            if (words > expected) {
+                std::cerr << "WARNING: obtained more data than expected ("
+                          << words << " " << sizeof(capnp::word)
+                          << "-byte words, expected "
+                          << expected << ")" << std::endl;
+            }
+            return words >= expected;
+        }
+    };
+    
+public:
+    CapnpRRClient(SynchronousTransport *transport) : //!!! ownership? shared ptr?
+        m_transport(transport),
+        m_completenessChecker(new CompletenessChecker) {
+        transport->setCompletenessChecker(m_completenessChecker);
+    }
+
+    ~CapnpRRClient() {
+        delete m_completenessChecker;
+    }
+
+    //!!! obviously, factor out all repetitive guff
+
+    //!!! list and load are supposed to be called by application code,
+    //!!! but the rest are only supposed to be called by the plugin --
+    //!!! sort out the api here
+
+    // Loader methods:
+
+    Vamp::HostExt::ListResponse
+    listPluginData() override {
+
+        if (!m_transport->isOK()) {
+            throw std::runtime_error("Piper server failed to start");
+        }
+
+        capnp::MallocMessageBuilder message;
+        RpcRequest::Builder builder = message.initRoot<RpcRequest>();
+        VampnProto::buildRpcRequest_List(builder);
+        ReqId id = getId();
+        builder.getId().setNumber(id);
+
+	auto karr = call(message);
+
+        capnp::FlatArrayMessageReader responseMessage(karr);
+        RpcResponse::Reader reader = responseMessage.getRoot<RpcResponse>();
+
+        checkResponseType(reader, RpcResponse::Response::Which::LIST, id);
+
+        Vamp::HostExt::ListResponse lr;
+        VampnProto::readListResponse(lr, reader.getResponse().getList());
+        return lr;
+    }
+    
+    Vamp::HostExt::LoadResponse
+    loadPlugin(const Vamp::HostExt::LoadRequest &req) override {
+
+        if (!m_transport->isOK()) {
+            throw std::runtime_error("Piper server failed to start");
+        }
+
+        Vamp::HostExt::LoadResponse resp;
+        PluginHandleMapper::Handle handle = serverLoad(req.pluginKey,
+                                                       req.inputSampleRate,
+                                                       req.adapterFlags,
+                                                       resp.staticData,
+                                                       resp.defaultConfiguration);
+
+        Vamp::Plugin *plugin = new PluginStub(this,
+                                              req.pluginKey,
+                                              req.inputSampleRate,
+                                              req.adapterFlags,
+                                              resp.staticData,
+                                              resp.defaultConfiguration);
+
+        m_mapper.addPlugin(handle, plugin);
+
+        resp.plugin = plugin;
+        return resp;
+    }
+
+    // PluginClient methods:
+    
+    virtual
+    Vamp::Plugin::OutputList
+    configure(PluginStub *plugin,
+              Vamp::HostExt::PluginConfiguration config) override {
+
+        if (!m_transport->isOK()) {
+            throw std::runtime_error("Piper server failed to start");
+        }
+
+        Vamp::HostExt::ConfigurationRequest request;
+        request.plugin = plugin;
+        request.configuration = config;
+
+        capnp::MallocMessageBuilder message;
+        RpcRequest::Builder builder = message.initRoot<RpcRequest>();
+
+        VampnProto::buildRpcRequest_Configure(builder, request, m_mapper);
+        ReqId id = getId();
+        builder.getId().setNumber(id);
+
+	auto karr = call(message);
+
+        capnp::FlatArrayMessageReader responseMessage(karr);
+        RpcResponse::Reader reader = responseMessage.getRoot<RpcResponse>();
+
+        //!!! handle (explicit) error case
+
+        checkResponseType(reader, RpcResponse::Response::Which::CONFIGURE, id);
+
+        Vamp::HostExt::ConfigurationResponse cr;
+        VampnProto::readConfigurationResponse(cr,
+                                              reader.getResponse().getConfigure(),
+                                              m_mapper);
+
+        return cr.outputs;
+    };
+    
+    virtual
+    Vamp::Plugin::FeatureSet
+    process(PluginStub *plugin,
+            std::vector<std::vector<float> > inputBuffers,
+            Vamp::RealTime timestamp) override {
+
+        if (!m_transport->isOK()) {
+            throw std::runtime_error("Piper server failed to start");
+        }
+
+        Vamp::HostExt::ProcessRequest request;
+        request.plugin = plugin;
+        request.inputBuffers = inputBuffers;
+        request.timestamp = timestamp;
+        
+        capnp::MallocMessageBuilder message;
+        RpcRequest::Builder builder = message.initRoot<RpcRequest>();
+        VampnProto::buildRpcRequest_Process(builder, request, m_mapper);
+	ReqId id = getId();
+        builder.getId().setNumber(id);
+
+	auto karr = call(message);
+
+        capnp::FlatArrayMessageReader responseMessage(karr);
+        RpcResponse::Reader reader = responseMessage.getRoot<RpcResponse>();
+
+        //!!! handle (explicit) error case
+
+        checkResponseType(reader, RpcResponse::Response::Which::PROCESS, id);
+
+        Vamp::HostExt::ProcessResponse pr;
+        VampnProto::readProcessResponse(pr,
+                                        reader.getResponse().getProcess(),
+                                        m_mapper);
+
+        return pr.features;
+    }
+
+    virtual Vamp::Plugin::FeatureSet
+    finish(PluginStub *plugin) override {
+
+        if (!m_transport->isOK()) {
+            throw std::runtime_error("Piper server failed to start");
+        }
+
+        Vamp::HostExt::FinishRequest request;
+        request.plugin = plugin;
+        
+        capnp::MallocMessageBuilder message;
+        RpcRequest::Builder builder = message.initRoot<RpcRequest>();
+
+        VampnProto::buildRpcRequest_Finish(builder, request, m_mapper);
+        ReqId id = getId();
+        builder.getId().setNumber(id);
+        
+	auto karr = call(message);
+
+        capnp::FlatArrayMessageReader responseMessage(karr);
+        RpcResponse::Reader reader = responseMessage.getRoot<RpcResponse>();
+
+        //!!! handle (explicit) error case
+
+        checkResponseType(reader, RpcResponse::Response::Which::FINISH, id);
+
+        Vamp::HostExt::ProcessResponse pr;
+        VampnProto::readFinishResponse(pr,
+                                       reader.getResponse().getFinish(),
+                                       m_mapper);
+
+        m_mapper.removePlugin(m_mapper.pluginToHandle(plugin));
+
+	// Don't delete the plugin. It's the plugin that is supposed
+	// to be calling us here
+        
+        return pr.features;
+    }
+
+    virtual void
+    reset(PluginStub *plugin,
+          Vamp::HostExt::PluginConfiguration config) override {
+
+        // Reload the plugin on the server side, and configure it as requested
+        
+        if (!m_transport->isOK()) {
+            throw std::runtime_error("Piper server failed to start");
+        }
+
+        if (m_mapper.havePlugin(plugin)) {
+            (void)finish(plugin); // server-side unload
+        }
+
+        Vamp::HostExt::PluginStaticData psd;
+        Vamp::HostExt::PluginConfiguration defaultConfig;
+        PluginHandleMapper::Handle handle =
+            serverLoad(plugin->getPluginKey(),
+                       plugin->getInputSampleRate(),
+                       plugin->getAdapterFlags(),
+                       psd, defaultConfig);
+
+        m_mapper.addPlugin(handle, plugin);
+
+        (void)configure(plugin, config);
+    }
+    
+private:
+    AssignedPluginHandleMapper m_mapper;
+    ReqId getId() {
+        //!!! todo: mutex
+        static ReqId m_nextId = 0;
+        return m_nextId++;
+    }
+
+    static
+    kj::Array<capnp::word>
+    toKJArray(const std::vector<char> &buffer) {
+	// We could do this whole thing with fewer copies, but let's
+	// see whether it matters first
+        size_t wordSize = sizeof(capnp::word);
+	size_t words = buffer.size() / wordSize;
+	kj::Array<capnp::word> karr(kj::heapArray<capnp::word>(words));
+	memcpy(karr.begin(), buffer.data(), words * wordSize);
+	return karr;
+    }
+
+    void
+    checkResponseType(const RpcResponse::Reader &r,
+                      RpcResponse::Response::Which type,
+                      ReqId id) {
+        
+        if (r.getResponse().which() != type) {
+            throw std::runtime_error("Wrong response type");
+        }
+        if (ReqId(r.getId().getNumber()) != id) {
+            throw std::runtime_error("Wrong response id");
+        }
+    }
+
+    kj::Array<capnp::word>
+    call(capnp::MallocMessageBuilder &message) {
+        auto arr = capnp::messageToFlatArray(message);
+        auto responseBuffer = m_transport->call(arr.asChars().begin(),
+                                                arr.asChars().size());
+	return toKJArray(responseBuffer);
+    }
+    
+    PluginHandleMapper::Handle
+    serverLoad(std::string key, float inputSampleRate, int adapterFlags,
+               Vamp::HostExt::PluginStaticData &psd,
+               Vamp::HostExt::PluginConfiguration &defaultConfig) {
+
+        Vamp::HostExt::LoadRequest request;
+        request.pluginKey = key;
+        request.inputSampleRate = inputSampleRate;
+        request.adapterFlags = adapterFlags;
+
+        capnp::MallocMessageBuilder message;
+        RpcRequest::Builder builder = message.initRoot<RpcRequest>();
+
+        VampnProto::buildRpcRequest_Load(builder, request);
+        ReqId id = getId();
+        builder.getId().setNumber(id);
+
+	auto karr = call(message);
+
+        //!!! ... --> will also need some way to kill this process
+        //!!! (from another thread)
+
+        capnp::FlatArrayMessageReader responseMessage(karr);
+        RpcResponse::Reader reader = responseMessage.getRoot<RpcResponse>();
+
+        //!!! handle (explicit) error case
+
+        checkResponseType(reader, RpcResponse::Response::Which::LOAD, id);
+        
+        const LoadResponse::Reader &lr = reader.getResponse().getLoad();
+        VampnProto::readExtractorStaticData(psd, lr.getStaticData());
+        VampnProto::readConfiguration(defaultConfig, lr.getDefaultConfiguration());
+        return lr.getHandle();
+    };     
+
+private:
+    SynchronousTransport *m_transport; //!!! I don't own this, but should I?
+    CompletenessChecker *m_completenessChecker; // I own this
+};
+
+}
+}
+
+#endif
--- a/vamp-client/Makefile	Thu Oct 13 14:31:10 2016 +0100
+++ b/vamp-client/Makefile	Thu Oct 13 17:00:06 2016 +0100
@@ -3,7 +3,7 @@
 # Generated by qmake (3.0) (Qt 5.7.0)
 # Project:  client.pro
 # Template: app
-# Command: /usr/bin/qmake -o Makefile client.pro
+# Command: /usr/lib/qt/bin/qmake -o Makefile client.pro
 #############################################################################
 
 MAKEFILE      = Makefile
@@ -16,7 +16,7 @@
 CFLAGS        = -pipe -O2 -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -Wall -W -D_REENTRANT -fPIC $(DEFINES)
 CXXFLAGS      = -I../../vamp-plugin-sdk -I.. -O2 -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -std=gnu++11 -Wall -W -D_REENTRANT -fPIC $(DEFINES)
 INCPATH       = -I. -isystem /usr/include/qt -isystem /usr/include/qt/QtCore -I../o -I/usr/lib/qt/mkspecs/linux-g++
-QMAKE         = /usr/bin/qmake
+QMAKE         = /usr/lib/qt/bin/qmake
 DEL_FILE      = rm -f
 CHK_DIR_EXISTS= test -d
 MKDIR         = mkdir -p
@@ -76,6 +76,9 @@
 		/usr/lib/qt/mkspecs/modules/qt_KCrash.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KDBusAddons.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KDeclarative.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KDEWebKit.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KDNSSD.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KEmoticons.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KGlobalAccel.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KGuiAddons.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KI18n.pri \
@@ -84,18 +87,22 @@
 		/usr/lib/qt/mkspecs/modules/qt_KIOFileWidgets.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KIOGui.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KIOWidgets.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KItemModels.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KItemViews.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KJobWidgets.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KNewStuff.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KNotifications.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KNotifyConfig.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KNTLM.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KParts.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KPlotting.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KService.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KTextWidgets.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KUnitConversion.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KWallet.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KWidgetsAddons.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KWindowSystem.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KXmlGui.pri \
-		/usr/lib/qt/mkspecs/modules/qt_lib_bluetooth.pri \
-		/usr/lib/qt/mkspecs/modules/qt_lib_bluetooth_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_bootstrap_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_clucene_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_concurrent.pri \
@@ -123,8 +130,6 @@
 		/usr/lib/qt/mkspecs/modules/qt_lib_multimediawidgets_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_network.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_network_private.pri \
-		/usr/lib/qt/mkspecs/modules/qt_lib_nfc.pri \
-		/usr/lib/qt/mkspecs/modules/qt_lib_nfc_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_opengl.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_opengl_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_openglextensions.pri \
@@ -144,7 +149,10 @@
 		/usr/lib/qt/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_quick.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_quick_private.pri \
+		/usr/lib/qt/mkspecs/modules/qt_lib_quickcontrols2.pri \
+		/usr/lib/qt/mkspecs/modules/qt_lib_quickcontrols2_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_quickparticles_private.pri \
+		/usr/lib/qt/mkspecs/modules/qt_lib_quicktemplates2_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_quickwidgets.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_quickwidgets_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_script.pri \
@@ -153,8 +161,6 @@
 		/usr/lib/qt/mkspecs/modules/qt_lib_scripttools_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_sensors.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_sensors_private.pri \
-		/usr/lib/qt/mkspecs/modules/qt_lib_serialport.pri \
-		/usr/lib/qt/mkspecs/modules/qt_lib_serialport_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_sql.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_sql_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_svg.pri \
@@ -206,7 +212,7 @@
 		/usr/lib/qt/mkspecs/features/yacc.prf \
 		/usr/lib/qt/mkspecs/features/lex.prf \
 		client.pro ProcessQtTransport.h \
-		CapnpClient.h \
+		CapnpRRClient.h \
 		Loader.h \
 		PluginClient.h \
 		PluginStub.h \
@@ -247,6 +253,9 @@
 		/usr/lib/qt/mkspecs/modules/qt_KCrash.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KDBusAddons.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KDeclarative.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KDEWebKit.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KDNSSD.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KEmoticons.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KGlobalAccel.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KGuiAddons.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KI18n.pri \
@@ -255,18 +264,22 @@
 		/usr/lib/qt/mkspecs/modules/qt_KIOFileWidgets.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KIOGui.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KIOWidgets.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KItemModels.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KItemViews.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KJobWidgets.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KNewStuff.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KNotifications.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KNotifyConfig.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KNTLM.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KParts.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KPlotting.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KService.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KTextWidgets.pri \
+		/usr/lib/qt/mkspecs/modules/qt_KUnitConversion.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KWallet.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KWidgetsAddons.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KWindowSystem.pri \
 		/usr/lib/qt/mkspecs/modules/qt_KXmlGui.pri \
-		/usr/lib/qt/mkspecs/modules/qt_lib_bluetooth.pri \
-		/usr/lib/qt/mkspecs/modules/qt_lib_bluetooth_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_bootstrap_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_clucene_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_concurrent.pri \
@@ -294,8 +307,6 @@
 		/usr/lib/qt/mkspecs/modules/qt_lib_multimediawidgets_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_network.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_network_private.pri \
-		/usr/lib/qt/mkspecs/modules/qt_lib_nfc.pri \
-		/usr/lib/qt/mkspecs/modules/qt_lib_nfc_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_opengl.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_opengl_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_openglextensions.pri \
@@ -315,7 +326,10 @@
 		/usr/lib/qt/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_quick.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_quick_private.pri \
+		/usr/lib/qt/mkspecs/modules/qt_lib_quickcontrols2.pri \
+		/usr/lib/qt/mkspecs/modules/qt_lib_quickcontrols2_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_quickparticles_private.pri \
+		/usr/lib/qt/mkspecs/modules/qt_lib_quicktemplates2_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_quickwidgets.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_quickwidgets_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_script.pri \
@@ -324,8 +338,6 @@
 		/usr/lib/qt/mkspecs/modules/qt_lib_scripttools_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_sensors.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_sensors_private.pri \
-		/usr/lib/qt/mkspecs/modules/qt_lib_serialport.pri \
-		/usr/lib/qt/mkspecs/modules/qt_lib_serialport_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_sql.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_sql_private.pri \
 		/usr/lib/qt/mkspecs/modules/qt_lib_svg.pri \
@@ -403,6 +415,9 @@
 /usr/lib/qt/mkspecs/modules/qt_KCrash.pri:
 /usr/lib/qt/mkspecs/modules/qt_KDBusAddons.pri:
 /usr/lib/qt/mkspecs/modules/qt_KDeclarative.pri:
+/usr/lib/qt/mkspecs/modules/qt_KDEWebKit.pri:
+/usr/lib/qt/mkspecs/modules/qt_KDNSSD.pri:
+/usr/lib/qt/mkspecs/modules/qt_KEmoticons.pri:
 /usr/lib/qt/mkspecs/modules/qt_KGlobalAccel.pri:
 /usr/lib/qt/mkspecs/modules/qt_KGuiAddons.pri:
 /usr/lib/qt/mkspecs/modules/qt_KI18n.pri:
@@ -411,18 +426,22 @@
 /usr/lib/qt/mkspecs/modules/qt_KIOFileWidgets.pri:
 /usr/lib/qt/mkspecs/modules/qt_KIOGui.pri:
 /usr/lib/qt/mkspecs/modules/qt_KIOWidgets.pri:
+/usr/lib/qt/mkspecs/modules/qt_KItemModels.pri:
 /usr/lib/qt/mkspecs/modules/qt_KItemViews.pri:
 /usr/lib/qt/mkspecs/modules/qt_KJobWidgets.pri:
+/usr/lib/qt/mkspecs/modules/qt_KNewStuff.pri:
 /usr/lib/qt/mkspecs/modules/qt_KNotifications.pri:
+/usr/lib/qt/mkspecs/modules/qt_KNotifyConfig.pri:
 /usr/lib/qt/mkspecs/modules/qt_KNTLM.pri:
+/usr/lib/qt/mkspecs/modules/qt_KParts.pri:
+/usr/lib/qt/mkspecs/modules/qt_KPlotting.pri:
 /usr/lib/qt/mkspecs/modules/qt_KService.pri:
 /usr/lib/qt/mkspecs/modules/qt_KTextWidgets.pri:
+/usr/lib/qt/mkspecs/modules/qt_KUnitConversion.pri:
 /usr/lib/qt/mkspecs/modules/qt_KWallet.pri:
 /usr/lib/qt/mkspecs/modules/qt_KWidgetsAddons.pri:
 /usr/lib/qt/mkspecs/modules/qt_KWindowSystem.pri:
 /usr/lib/qt/mkspecs/modules/qt_KXmlGui.pri:
-/usr/lib/qt/mkspecs/modules/qt_lib_bluetooth.pri:
-/usr/lib/qt/mkspecs/modules/qt_lib_bluetooth_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_bootstrap_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_clucene_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_concurrent.pri:
@@ -450,8 +469,6 @@
 /usr/lib/qt/mkspecs/modules/qt_lib_multimediawidgets_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_network.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_network_private.pri:
-/usr/lib/qt/mkspecs/modules/qt_lib_nfc.pri:
-/usr/lib/qt/mkspecs/modules/qt_lib_nfc_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_opengl.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_opengl_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_openglextensions.pri:
@@ -471,7 +488,10 @@
 /usr/lib/qt/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_quick.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_quick_private.pri:
+/usr/lib/qt/mkspecs/modules/qt_lib_quickcontrols2.pri:
+/usr/lib/qt/mkspecs/modules/qt_lib_quickcontrols2_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_quickparticles_private.pri:
+/usr/lib/qt/mkspecs/modules/qt_lib_quicktemplates2_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_quickwidgets.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_quickwidgets_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_script.pri:
@@ -480,8 +500,6 @@
 /usr/lib/qt/mkspecs/modules/qt_lib_scripttools_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_sensors.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_sensors_private.pri:
-/usr/lib/qt/mkspecs/modules/qt_lib_serialport.pri:
-/usr/lib/qt/mkspecs/modules/qt_lib_serialport_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_sql.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_sql_private.pri:
 /usr/lib/qt/mkspecs/modules/qt_lib_svg.pri:
@@ -548,7 +566,7 @@
 distdir: FORCE
 	@test -d $(DISTDIR) || mkdir -p $(DISTDIR)
 	$(COPY_FILE) --parents $(DIST) $(DISTDIR)/
-	$(COPY_FILE) --parents ProcessQtTransport.h CapnpClient.h Loader.h PluginClient.h PluginStub.h SynchronousTransport.h $(DISTDIR)/
+	$(COPY_FILE) --parents ProcessQtTransport.h CapnpRRClient.h Loader.h PluginClient.h PluginStub.h SynchronousTransport.h $(DISTDIR)/
 	$(COPY_FILE) --parents client.cpp ../vamp-capnp/piper.capnp.c++ $(DISTDIR)/
 
 
@@ -589,7 +607,12 @@
 
 ####### Compile
 
-../o/client.o: client.cpp 
+../o/client.o: client.cpp ProcessQtTransport.h \
+		SynchronousTransport.h \
+		CapnpRRClient.h \
+		Loader.h \
+		PluginClient.h \
+		PluginStub.h
 	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../o/client.o client.cpp
 
 ../o/piper.capnp.o: ../vamp-capnp/piper.capnp.c++ ../vamp-capnp/piper.capnp.h
--- a/vamp-client/client.cpp	Thu Oct 13 14:31:10 2016 +0100
+++ b/vamp-client/client.cpp	Thu Oct 13 17:00:06 2016 +0100
@@ -1,6 +1,6 @@
 
 #include "ProcessQtTransport.h"
-#include "CapnpClient.h"
+#include "CapnpRRClient.h"
 
 #include <stdexcept>
 
@@ -10,7 +10,7 @@
 int main(int, char **)
 {
     piper::vampclient::ProcessQtTransport transport("../bin/piper-vamp-server");
-    piper::vampclient::CapnpClient client(&transport);
+    piper::vampclient::CapnpRRClient client(&transport);
 
     Vamp::HostExt::ListResponse lr = client.listPluginData();
     cerr << "Plugins available:" << endl;
@@ -58,6 +58,5 @@
     (void)plugin->getRemainingFeatures();
 
     delete plugin;
-    //!!! -- and also implement reset(), which will need to reconstruct internally
 }
 
--- a/vamp-client/client.pro	Thu Oct 13 14:31:10 2016 +0100
+++ b/vamp-client/client.pro	Thu Oct 13 17:00:06 2016 +0100
@@ -30,7 +30,7 @@
         
 HEADERS += \
         ProcessQtTransport.h \
-        CapnpClient.h \
+        CapnpRRClient.h \
         Loader.h \
         PluginClient.h \
         PluginStub.h \