changeset 92:21f8af53eaf0

Reorganise some classes
author Chris Cannam <c.cannam@qmul.ac.uk>
date Thu, 13 Oct 2016 12:02:44 +0100
parents c897c9a8daf1
children fbce91785d35
files vamp-client/CapnpMessageCompletenessChecker.h vamp-client/Makefile vamp-client/PipedQProcessTransport.h vamp-client/PiperCapnpClient.h vamp-client/PiperClient.h vamp-client/PiperPluginStub.h vamp-client/PiperStubPlugin.h vamp-client/SynchronousTransport.h vamp-client/client.cpp vamp-client/client.pro vamp-server/server.cpp
diffstat 11 files changed, 327 insertions(+), 329 deletions(-) [+]
line wrap: on
line diff
--- a/vamp-client/CapnpMessageCompletenessChecker.h	Thu Oct 13 11:33:19 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-
-#ifndef CAPNP_MESSAGE_COMPLETENESS_CHECKER_H
-#define CAPNP_MESSAGE_COMPLETENESS_CHECKER_H
-
-#include "SynchronousTransport.h" //!!!
-
-#include <capnp/serialize.h>
-
-#include <iostream>
-
-namespace piper { //!!! change
-
-class CapnpMessageCompletenessChecker : public MessageCompletenessChecker
-{
-public:
-    bool isComplete(const std::vector<char> &message) const override {
-
-        // a bit liberal with the copies here
-        size_t wordSize = sizeof(capnp::word);
-	size_t words = message.size() / wordSize;
-	kj::Array<capnp::word> karr(kj::heapArray<capnp::word>(words));
-	memcpy(karr.begin(), message.data(), words * wordSize);
-
-        size_t expected = capnp::expectedSizeInWordsFromPrefix(karr);
-
-        if (words > expected) {
-            std::cerr << "WARNING: obtained more data than expected ("
-                      << words << " " << wordSize << "-byte words, expected "
-                      << expected << ")" << std::endl;
-        }
-        
-        return words >= expected;
-    }
-};
-
-}
-
-#endif
--- a/vamp-client/Makefile	Thu Oct 13 11:33:19 2016 +0100
+++ b/vamp-client/Makefile	Thu Oct 13 12:02:44 2016 +0100
@@ -205,11 +205,10 @@
 		/usr/lib/qt/mkspecs/features/testcase_targets.prf \
 		/usr/lib/qt/mkspecs/features/yacc.prf \
 		/usr/lib/qt/mkspecs/features/lex.prf \
-		client.pro CapnpMessageCompletenessChecker.h \
-		PipedQProcessTransport.h \
+		client.pro PipedQProcessTransport.h \
 		PiperCapnpClient.h \
 		PiperClient.h \
-		PiperStubPlugin.h \
+		PiperPluginStub.h \
 		SynchronousTransport.h client.cpp \
 		../vamp-capnp/piper.capnp.c++
 QMAKE_TARGET  = client
@@ -548,7 +547,7 @@
 distdir: FORCE
 	@test -d $(DISTDIR) || mkdir -p $(DISTDIR)
 	$(COPY_FILE) --parents $(DIST) $(DISTDIR)/
-	$(COPY_FILE) --parents CapnpMessageCompletenessChecker.h PipedQProcessTransport.h PiperCapnpClient.h PiperClient.h PiperStubPlugin.h SynchronousTransport.h $(DISTDIR)/
+	$(COPY_FILE) --parents PipedQProcessTransport.h PiperCapnpClient.h PiperClient.h PiperPluginStub.h SynchronousTransport.h $(DISTDIR)/
 	$(COPY_FILE) --parents client.cpp ../vamp-capnp/piper.capnp.c++ $(DISTDIR)/
 
 
@@ -589,11 +588,11 @@
 
 ####### Compile
 
-../o/client.o: client.cpp PiperClient.h \
-		PiperStubPlugin.h \
-		CapnpMessageCompletenessChecker.h \
+../o/client.o: client.cpp PipedQProcessTransport.h \
 		SynchronousTransport.h \
-		PipedQProcessTransport.h
+		PiperCapnpClient.h \
+		PiperClient.h \
+		PiperPluginStub.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/PipedQProcessTransport.h	Thu Oct 13 11:33:19 2016 +0100
+++ b/vamp-client/PipedQProcessTransport.h	Thu Oct 13 12:02:44 2016 +0100
@@ -14,9 +14,8 @@
 class PipedQProcessTransport : public SynchronousTransport
 {
 public:
-    PipedQProcessTransport(QString processName,
-                           MessageCompletenessChecker *checker) : //!!! ownership
-        m_completenessChecker(checker) {
+    PipedQProcessTransport(QString processName) :
+        m_completenessChecker(0) {
         m_process = new QProcess();
         m_process->setReadChannel(QProcess::StandardOutput);
         m_process->setProcessChannelMode(QProcess::ForwardedErrorChannel);
@@ -41,47 +40,47 @@
         }
     }
 
-    bool isOK() const override {
+    void
+    setCompletenessChecker(MessageCompletenessChecker *checker) {
+        //!!! ownership?
+        m_completenessChecker = checker;
+    }
+    
+    bool
+    isOK() const override {
         return m_process != nullptr;
     }
     
     std::vector<char>
     call(const char *ptr, size_t size) override {
 
+        if (!m_completenessChecker) {
+            throw std::logic_error("No completeness checker set on transport");
+        }
+        
         m_process->write(ptr, size);
         
         std::vector<char> buffer;
-        size_t wordSize = sizeof(capnp::word);
         bool complete = false;
         
         while (!complete) {
 
             m_process->waitForReadyRead(1000);
             qint64 byteCount = m_process->bytesAvailable();
-            qint64 wordCount = byteCount / wordSize;
 
-            if (!wordCount) {
+            if (!byteCount) {
                 if (m_process->state() == QProcess::NotRunning) {
                     std::cerr << "ERROR: Subprocess exited: Load failed" << std::endl;
                     throw std::runtime_error("Piper server exited unexpectedly");
                 }
             } else {
-                // only read whole words
-                byteCount = wordCount * wordSize;
                 size_t formerSize = buffer.size();
                 buffer.resize(formerSize + byteCount);
                 m_process->read(buffer.data() + formerSize, byteCount);
                 complete = m_completenessChecker->isComplete(buffer);
             }
         }
-/*
-        cerr << "buffer = ";
-        for (int i = 0; i < buffer.size(); ++i) {
-            if (i % 16 == 0) cerr << "\n";
-            cerr << int(buffer[i]) << " ";
-        }
-        cerr << "\n";
-*/        
+
         return buffer;
     }
     
--- a/vamp-client/PiperCapnpClient.h	Thu Oct 13 11:33:19 2016 +0100
+++ b/vamp-client/PiperCapnpClient.h	Thu Oct 13 12:02:44 2016 +0100
@@ -3,24 +3,47 @@
 #define PIPER_CAPNP_CLIENT_H
 
 #include "PiperClient.h"
+#include "PiperPluginStub.h"
 #include "SynchronousTransport.h"
 
 #include "vamp-support/AssignedPluginHandleMapper.h"
 #include "vamp-capnp/VampnProto.h"
 
+#include <capnp/serialize.h>
+
 namespace piper { //!!! change
 
-class PiperCapnpClient : public PiperStubPluginClientInterface
+class PiperCapnpClient : public PiperPluginClientInterface,
+                         public PiperLoaderInterface
 {
     // 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:
     PiperCapnpClient(SynchronousTransport *transport) : //!!! ownership? shared ptr?
-        m_transport(transport) {
+        m_transport(transport),
+        m_completenessChecker(new CompletenessChecker) {
+        transport->setCompletenessChecker(m_completenessChecker);
     }
 
     ~PiperCapnpClient() {
+        delete m_completenessChecker;
     }
 
     //!!! obviously, factor out all repetitive guff
@@ -41,7 +64,7 @@
         PluginHandleMapper::Handle handle =
             serverLoad(key, inputSampleRate, adapterFlags, psd, defaultConfig);
 
-        Vamp::Plugin *plugin = new PiperStubPlugin(this,
+        Vamp::Plugin *plugin = new PiperPluginStub(this,
                                                    key,
                                                    inputSampleRate,
                                                    adapterFlags,
@@ -95,7 +118,7 @@
 protected:
     virtual
     Vamp::Plugin::OutputList
-    configure(PiperStubPlugin *plugin,
+    configure(PiperPluginStub *plugin,
               Vamp::HostExt::PluginConfiguration config) override {
 
         if (!m_transport->isOK()) {
@@ -134,7 +157,7 @@
     
     virtual
     Vamp::Plugin::FeatureSet
-    process(PiperStubPlugin *plugin,
+    process(PiperPluginStub *plugin,
             std::vector<std::vector<float> > inputBuffers,
             Vamp::RealTime timestamp) override {
 
@@ -174,7 +197,7 @@
     }
 
     virtual Vamp::Plugin::FeatureSet
-    finish(PiperStubPlugin *plugin) override {
+    finish(PiperPluginStub *plugin) override {
 
         if (!m_transport->isOK()) {
             throw std::runtime_error("Piper server failed to start");
@@ -215,7 +238,7 @@
     }
 
     virtual void
-    reset(PiperStubPlugin *plugin,
+    reset(PiperPluginStub *plugin,
           Vamp::HostExt::PluginConfiguration config) override {
 
         // Reload the plugin on the server side, and configure it as requested
@@ -249,6 +272,7 @@
         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
@@ -275,6 +299,7 @@
 
 private:
     SynchronousTransport *m_transport; //!!! I don't own this, but should I?
+    CompletenessChecker *m_completenessChecker; // I own this
 };
 
 }
--- a/vamp-client/PiperClient.h	Thu Oct 13 11:33:19 2016 +0100
+++ b/vamp-client/PiperClient.h	Thu Oct 13 12:02:44 2016 +0100
@@ -6,30 +6,38 @@
 
 namespace piper { //!!! change
 
-class PiperStubPlugin;
+class PiperPluginStub;
 
-class PiperStubPluginClientInterface
+class PiperLoaderInterface
 {
-    friend class PiperStubPlugin;
+public:
+    virtual
+    Vamp::Plugin *
+    load(std::string key, float inputSampleRate, int adapterFlags) = 0;
+};
+
+class PiperPluginClientInterface
+{
+    friend class PiperPluginStub;
     
 protected:
     virtual
     Vamp::Plugin::OutputList
-    configure(PiperStubPlugin *plugin,
+    configure(PiperPluginStub *plugin,
               Vamp::HostExt::PluginConfiguration config) = 0;
     
     virtual
     Vamp::Plugin::FeatureSet
-    process(PiperStubPlugin *plugin,
+    process(PiperPluginStub *plugin,
             std::vector<std::vector<float> > inputBuffers,
             Vamp::RealTime timestamp) = 0;
 
     virtual Vamp::Plugin::FeatureSet
-    finish(PiperStubPlugin *plugin) = 0;
+    finish(PiperPluginStub *plugin) = 0;
 
     virtual
     void
-    reset(PiperStubPlugin *plugin,
+    reset(PiperPluginStub *plugin,
           Vamp::HostExt::PluginConfiguration config) = 0;
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vamp-client/PiperPluginStub.h	Thu Oct 13 12:02:44 2016 +0100
@@ -0,0 +1,240 @@
+
+#ifndef PIPER_STUB_PLUGIN_H
+#define PIPER_STUB_PLUGIN_H
+
+#include <vamp-hostsdk/Plugin.h>
+#include <vamp-hostsdk/PluginLoader.h>
+#include <vamp-hostsdk/PluginStaticData.h>
+#include <vamp-hostsdk/PluginConfiguration.h>
+
+#include <cstdint>
+
+#include "PiperClient.h"
+
+namespace piper { //!!! should be something else
+
+class PiperPluginStub : public Vamp::Plugin
+{
+    enum State {
+        Loaded, Configured, Finished
+    };
+    
+public:
+    PiperPluginStub(PiperPluginClientInterface *client,
+                    std::string pluginKey,
+                    float inputSampleRate,
+                    int adapterFlags,
+                    Vamp::HostExt::PluginStaticData psd,
+                    Vamp::HostExt::PluginConfiguration defaultConfig) :
+        Plugin(inputSampleRate),
+        m_client(client),
+        m_key(pluginKey),
+        m_adapterFlags(adapterFlags),
+        m_state(Loaded),
+        m_psd(psd),
+        m_defaultConfig(defaultConfig),
+        m_config(defaultConfig)
+    { }
+
+    virtual ~PiperPluginStub() {
+        if (m_state != Finished) {
+	    (void)m_client->finish(this);
+        }
+    }
+    
+    virtual std::string getIdentifier() const {
+        return m_psd.basic.identifier;
+    }
+
+    virtual std::string getName() const {
+        return m_psd.basic.name;
+    }
+
+    virtual std::string getDescription() const {
+        return m_psd.basic.description;
+    }
+
+    virtual std::string getMaker() const {
+        return m_psd.maker;
+    }
+
+    virtual std::string getCopyright() const {
+        return m_psd.copyright;
+    }
+
+    virtual int getPluginVersion() const {
+        return m_psd.pluginVersion;
+    }
+
+    virtual ParameterList getParameterDescriptors() const {
+        return m_psd.parameters;
+    }
+
+    virtual float getParameter(std::string name) const {
+        if (m_config.parameterValues.find(name) != m_config.parameterValues.end()) {
+            return m_config.parameterValues.at(name);
+        } else {
+            return 0.f;
+        }
+    }
+
+    virtual void setParameter(std::string name, float value) {
+        if (m_state != Loaded) {
+            throw std::logic_error("Can't set parameter after plugin initialised");
+        }
+        m_config.parameterValues[name] = value;
+    }
+
+    virtual ProgramList getPrograms() const {
+        return m_psd.programs;
+    }
+
+    virtual std::string getCurrentProgram() const {
+        return m_config.currentProgram;
+    }
+    
+    virtual void selectProgram(std::string program) {
+        if (m_state != Loaded) {
+            throw std::logic_error("Can't select program after plugin initialised");
+        }
+        m_config.currentProgram = program;
+    }
+
+    virtual bool initialise(size_t inputChannels,
+                            size_t stepSize,
+                            size_t blockSize) {
+
+        if (m_state != Loaded) {
+            throw std::logic_error("Plugin has already been initialised");
+        }
+        
+        m_config.channelCount = inputChannels;
+        m_config.stepSize = stepSize;
+        m_config.blockSize = blockSize;
+
+        m_outputs = m_client->configure(this, m_config);
+
+        if (!m_outputs.empty()) {
+            m_state = Configured;
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    virtual void reset() {
+        
+        if (m_state == Loaded) {
+            // reset is a no-op if the plugin hasn't been initialised yet
+            return;
+        }
+        
+        m_client->reset(this, m_config);
+
+        m_state = Configured;
+    }
+
+    virtual InputDomain getInputDomain() const {
+        return m_psd.inputDomain;
+    }
+
+    virtual size_t getPreferredBlockSize() const {
+        return m_defaultConfig.blockSize;
+    }
+
+    virtual size_t getPreferredStepSize() const {
+        return m_defaultConfig.stepSize;
+    }
+
+    virtual size_t getMinChannelCount() const {
+        return m_psd.minChannelCount;
+    }
+
+    virtual size_t getMaxChannelCount() const {
+        return m_psd.maxChannelCount;
+    }
+
+    virtual OutputList getOutputDescriptors() const {
+        if (m_state == Configured) {
+            return m_outputs;
+        }
+
+        //!!! todo: figure out for which hosts (and adapters?) it may
+        //!!! be a problem that the output descriptors are incomplete
+        //!!! here. Any such hosts/adapters are broken, but I bet they
+        //!!! exist
+        
+        OutputList staticOutputs;
+        for (const auto &o: m_psd.basicOutputInfo) {
+            OutputDescriptor od;
+            od.identifier = o.identifier;
+            od.name = o.name;
+            od.description = o.description;
+            staticOutputs.push_back(od);
+        }
+        return staticOutputs;
+    }
+
+    virtual FeatureSet process(const float *const *inputBuffers,
+			       Vamp::RealTime timestamp) {
+
+        if (m_state == Loaded) {
+            throw std::logic_error("Plugin has not been initialised");
+        }
+        if (m_state == Finished) {
+            throw std::logic_error("Plugin has already been disposed of");
+        }
+
+        //!!! ew
+        std::vector<std::vector<float> > vecbuf;
+        for (int c = 0; c < m_config.channelCount; ++c) {
+            vecbuf.push_back(std::vector<float>
+                             (inputBuffers[c],
+                              inputBuffers[c] + m_config.blockSize));
+        }
+        
+        return m_client->process(this, vecbuf, timestamp);
+    }
+
+    virtual FeatureSet getRemainingFeatures() {
+
+        if (m_state == Loaded) {
+            throw std::logic_error("Plugin has not been configured");
+        }
+        if (m_state == Finished) {
+            throw std::logic_error("Plugin has already been disposed of");
+        }
+
+        m_state = Finished;
+
+        return m_client->finish(this);
+    }
+
+    // Not Plugin methods, but needed by the PiperClient to support reloads:
+    
+    virtual float getInputSampleRate() const {
+        return m_inputSampleRate;
+    }
+
+    virtual std::string getPluginKey() const {
+        return m_key;
+    }
+
+    virtual int getAdapterFlags() const {
+        return m_adapterFlags;
+    }
+    
+private:
+    PiperPluginClientInterface *m_client;
+    std::string m_key;
+    int m_adapterFlags;
+    State m_state;
+    Vamp::HostExt::PluginStaticData m_psd;
+    OutputList m_outputs;
+    Vamp::HostExt::PluginConfiguration m_defaultConfig;
+    Vamp::HostExt::PluginConfiguration m_config;
+};
+
+}
+
+#endif
--- a/vamp-client/PiperStubPlugin.h	Thu Oct 13 11:33:19 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,240 +0,0 @@
-
-#ifndef PIPER_STUB_PLUGIN_H
-#define PIPER_STUB_PLUGIN_H
-
-#include <vamp-hostsdk/Plugin.h>
-#include <vamp-hostsdk/PluginLoader.h>
-#include <vamp-hostsdk/PluginStaticData.h>
-#include <vamp-hostsdk/PluginConfiguration.h>
-
-#include <cstdint>
-
-#include "PiperClient.h"
-
-namespace piper { //!!! should be something else
-
-class PiperStubPlugin : public Vamp::Plugin
-{
-    enum State {
-        Loaded, Configured, Finished
-    };
-    
-public:
-    PiperStubPlugin(PiperStubPluginClientInterface *client,
-                    std::string pluginKey,
-                    float inputSampleRate,
-                    int adapterFlags,
-                    Vamp::HostExt::PluginStaticData psd,
-                    Vamp::HostExt::PluginConfiguration defaultConfig) :
-        Plugin(inputSampleRate),
-        m_client(client),
-        m_key(pluginKey),
-        m_adapterFlags(adapterFlags),
-        m_state(Loaded),
-        m_psd(psd),
-        m_defaultConfig(defaultConfig),
-        m_config(defaultConfig)
-    { }
-
-    virtual ~PiperStubPlugin() {
-        if (m_state != Finished) {
-	    (void)m_client->finish(this);
-        }
-    }
-    
-    virtual std::string getIdentifier() const {
-        return m_psd.basic.identifier;
-    }
-
-    virtual std::string getName() const {
-        return m_psd.basic.name;
-    }
-
-    virtual std::string getDescription() const {
-        return m_psd.basic.description;
-    }
-
-    virtual std::string getMaker() const {
-        return m_psd.maker;
-    }
-
-    virtual std::string getCopyright() const {
-        return m_psd.copyright;
-    }
-
-    virtual int getPluginVersion() const {
-        return m_psd.pluginVersion;
-    }
-
-    virtual ParameterList getParameterDescriptors() const {
-        return m_psd.parameters;
-    }
-
-    virtual float getParameter(std::string name) const {
-        if (m_config.parameterValues.find(name) != m_config.parameterValues.end()) {
-            return m_config.parameterValues.at(name);
-        } else {
-            return 0.f;
-        }
-    }
-
-    virtual void setParameter(std::string name, float value) {
-        if (m_state != Loaded) {
-            throw std::logic_error("Can't set parameter after plugin initialised");
-        }
-        m_config.parameterValues[name] = value;
-    }
-
-    virtual ProgramList getPrograms() const {
-        return m_psd.programs;
-    }
-
-    virtual std::string getCurrentProgram() const {
-        return m_config.currentProgram;
-    }
-    
-    virtual void selectProgram(std::string program) {
-        if (m_state != Loaded) {
-            throw std::logic_error("Can't select program after plugin initialised");
-        }
-        m_config.currentProgram = program;
-    }
-
-    virtual bool initialise(size_t inputChannels,
-                            size_t stepSize,
-                            size_t blockSize) {
-
-        if (m_state != Loaded) {
-            throw std::logic_error("Plugin has already been initialised");
-        }
-        
-        m_config.channelCount = inputChannels;
-        m_config.stepSize = stepSize;
-        m_config.blockSize = blockSize;
-
-        m_outputs = m_client->configure(this, m_config);
-
-        if (!m_outputs.empty()) {
-            m_state = Configured;
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    virtual void reset() {
-        
-        if (m_state == Loaded) {
-            // reset is a no-op if the plugin hasn't been initialised yet
-            return;
-        }
-        
-        m_client->reset(this, m_config);
-
-        m_state = Configured;
-    }
-
-    virtual InputDomain getInputDomain() const {
-        return m_psd.inputDomain;
-    }
-
-    virtual size_t getPreferredBlockSize() const {
-        return m_defaultConfig.blockSize;
-    }
-
-    virtual size_t getPreferredStepSize() const {
-        return m_defaultConfig.stepSize;
-    }
-
-    virtual size_t getMinChannelCount() const {
-        return m_psd.minChannelCount;
-    }
-
-    virtual size_t getMaxChannelCount() const {
-        return m_psd.maxChannelCount;
-    }
-
-    virtual OutputList getOutputDescriptors() const {
-        if (m_state == Configured) {
-            return m_outputs;
-        }
-
-        //!!! todo: figure out for which hosts (and adapters?) it may
-        //!!! be a problem that the output descriptors are incomplete
-        //!!! here. Any such hosts/adapters are broken, but I bet they
-        //!!! exist
-        
-        OutputList staticOutputs;
-        for (const auto &o: m_psd.basicOutputInfo) {
-            OutputDescriptor od;
-            od.identifier = o.identifier;
-            od.name = o.name;
-            od.description = o.description;
-            staticOutputs.push_back(od);
-        }
-        return staticOutputs;
-    }
-
-    virtual FeatureSet process(const float *const *inputBuffers,
-			       Vamp::RealTime timestamp) {
-
-        if (m_state == Loaded) {
-            throw std::logic_error("Plugin has not been initialised");
-        }
-        if (m_state == Finished) {
-            throw std::logic_error("Plugin has already been disposed of");
-        }
-
-        //!!! ew
-        std::vector<std::vector<float> > vecbuf;
-        for (int c = 0; c < m_config.channelCount; ++c) {
-            vecbuf.push_back(std::vector<float>
-                             (inputBuffers[c],
-                              inputBuffers[c] + m_config.blockSize));
-        }
-        
-        return m_client->process(this, vecbuf, timestamp);
-    }
-
-    virtual FeatureSet getRemainingFeatures() {
-
-        if (m_state == Loaded) {
-            throw std::logic_error("Plugin has not been configured");
-        }
-        if (m_state == Finished) {
-            throw std::logic_error("Plugin has already been disposed of");
-        }
-
-        m_state = Finished;
-
-        return m_client->finish(this);
-    }
-
-    // Not Plugin methods, but needed by the PiperClient to support reloads:
-    
-    virtual float getInputSampleRate() const {
-        return m_inputSampleRate;
-    }
-
-    virtual std::string getPluginKey() const {
-        return m_key;
-    }
-
-    virtual int getAdapterFlags() const {
-        return m_adapterFlags;
-    }
-    
-private:
-    PiperStubPluginClientInterface *m_client;
-    std::string m_key;
-    int m_adapterFlags;
-    State m_state;
-    Vamp::HostExt::PluginStaticData m_psd;
-    OutputList m_outputs;
-    Vamp::HostExt::PluginConfiguration m_defaultConfig;
-    Vamp::HostExt::PluginConfiguration m_config;
-};
-
-}
-
-#endif
--- a/vamp-client/SynchronousTransport.h	Thu Oct 13 11:33:19 2016 +0100
+++ b/vamp-client/SynchronousTransport.h	Thu Oct 13 12:02:44 2016 +0100
@@ -3,12 +3,26 @@
 #define PIPER_SYNCHRONOUS_TRANSPORT_H
 
 #include <vector>
+#include <cstdlib>
 
 namespace piper {
 
+class MessageCompletenessChecker // interface
+{
+public:
+    virtual ~MessageCompletenessChecker() = default;
+    
+    virtual bool isComplete(const std::vector<char> &message) const = 0;
+};
+
 class SynchronousTransport // interface
 {
 public:
+    virtual ~SynchronousTransport() = default;
+    
+    //!!! I do not take ownership
+    virtual void setCompletenessChecker(MessageCompletenessChecker *) = 0;
+    
     //!!! how to handle errors -- exception or return value? often an
     //!!! error (e.g. server has exited) may mean the transport can no
     //!!! longer be used at all
@@ -17,12 +31,6 @@
     virtual bool isOK() const = 0;
 };
 
-class MessageCompletenessChecker // interface
-{
-public:
-    virtual bool isComplete(const std::vector<char> &message) const = 0;
-};
-
 }
 
 #endif
--- a/vamp-client/client.cpp	Thu Oct 13 11:33:19 2016 +0100
+++ b/vamp-client/client.cpp	Thu Oct 13 12:02:44 2016 +0100
@@ -1,6 +1,4 @@
 
-#include "PiperStubPlugin.h"
-#include "CapnpMessageCompletenessChecker.h"
 #include "PipedQProcessTransport.h"
 #include "PiperCapnpClient.h"
 
@@ -11,8 +9,7 @@
 
 int main(int, char **)
 {
-    piper::CapnpMessageCompletenessChecker checker;
-    piper::PipedQProcessTransport transport("../bin/piper-vamp-server", &checker);
+    piper::PipedQProcessTransport transport("../bin/piper-vamp-server");
     piper::PiperCapnpClient client(&transport);
     
     Vamp::Plugin *plugin = client.load("vamp-example-plugins:zerocrossing", 16, 0);
--- a/vamp-client/client.pro	Thu Oct 13 11:33:19 2016 +0100
+++ b/vamp-client/client.pro	Thu Oct 13 12:02:44 2016 +0100
@@ -29,11 +29,10 @@
         ../vamp-capnp/piper.capnp.c++
         
 HEADERS += \
-        CapnpMessageCompletenessChecker.h \
         PipedQProcessTransport.h \
         PiperCapnpClient.h \
         PiperClient.h \
-        PiperStubPlugin.h \
+        PiperPluginStub.h \
         SynchronousTransport.h
         
 
--- a/vamp-server/server.cpp	Thu Oct 13 11:33:19 2016 +0100
+++ b/vamp-server/server.cpp	Thu Oct 13 12:02:44 2016 +0100
@@ -295,6 +295,7 @@
 
 	    if (request.type == RRType::Finish) {
 		auto h = mapper.pluginToHandle(request.finishRequest.plugin);
+                cerr << "deleting the plugin with handle " << h << endl;
 		mapper.removePlugin(h);
 		delete request.finishRequest.plugin;
 	    }