changeset 80:d9e85a65d45b

Inching toward a client
author Chris Cannam <c.cannam@qmul.ac.uk>
date Tue, 11 Oct 2016 15:49:28 +0100
parents f4497c1da43d
children c6b6051b1b1a
files vamp-capnp/VampnProto.h vamp-client/Makefile vamp-client/client.cpp vamp-client/stub.h vamp-json/VampJson.h vamp-support/AssignedPluginHandleMapper.h vamp-support/CountingPluginHandleMapper.h
diffstat 7 files changed, 252 insertions(+), 101 deletions(-) [+]
line wrap: on
line diff
--- a/vamp-capnp/VampnProto.h	Tue Oct 11 14:38:04 2016 +0100
+++ b/vamp-capnp/VampnProto.h	Tue Oct 11 15:49:28 2016 +0100
@@ -40,6 +40,8 @@
 #include <vamp-hostsdk/Plugin.h>
 #include <vamp-hostsdk/PluginLoader.h>
 #include <vamp-hostsdk/PluginStaticData.h>
+#include <vamp-hostsdk/PluginConfiguration.h>
+#include <vamp-hostsdk/RequestResponse.h>
 
 #include "vamp-support/PluginHandleMapper.h"
 #include "vamp-support/PluginOutputIdMapper.h"
@@ -560,7 +562,7 @@
         resp.plugin = pmapper.handleToPlugin(r.getHandle());
         readExtractorStaticData(resp.staticData, r.getStaticData());
         readConfiguration(resp.defaultConfiguration,
-                                r.getDefaultConfiguration());
+                          r.getDefaultConfiguration());
     }
 
     static void
@@ -718,7 +720,7 @@
 
     static void
     buildRpcResponse_List(RpcResponse::Builder &b,
-                           const Vamp::HostExt::ListResponse &resp) {
+                          const Vamp::HostExt::ListResponse &resp) {
 
         auto r = b.getResponse().initList();
         auto p = r.initAvailable(resp.available.size());
@@ -730,15 +732,15 @@
     
     static void
     buildRpcRequest_Load(RpcRequest::Builder &b,
-                          const Vamp::HostExt::LoadRequest &req) {
+                         const Vamp::HostExt::LoadRequest &req) {
         auto u = b.getRequest().initLoad();
         buildLoadRequest(u, req);
     }
 
     static void
     buildRpcResponse_Load(RpcResponse::Builder &b,
-                           const Vamp::HostExt::LoadResponse &resp,
-                           const PluginHandleMapper &pmapper) {
+                          const Vamp::HostExt::LoadResponse &resp,
+                          const PluginHandleMapper &pmapper) {
 
         if (resp.plugin) {
             auto u = b.getResponse().initLoad();
@@ -750,16 +752,16 @@
 
     static void
     buildRpcRequest_Configure(RpcRequest::Builder &b,
-                               const Vamp::HostExt::ConfigurationRequest &cr,
-                               const PluginHandleMapper &pmapper) {
+                              const Vamp::HostExt::ConfigurationRequest &cr,
+                              const PluginHandleMapper &pmapper) {
         auto u = b.getRequest().initConfigure();
         buildConfigurationRequest(u, cr, pmapper);
     }
 
     static void
     buildRpcResponse_Configure(RpcResponse::Builder &b,
-                                const Vamp::HostExt::ConfigurationResponse &cr,
-                                const PluginHandleMapper &pmapper) {
+                               const Vamp::HostExt::ConfigurationResponse &cr,
+                               const PluginHandleMapper &pmapper) {
 
         if (!cr.outputs.empty()) {
             auto u = b.getResponse().initConfigure();
@@ -772,16 +774,16 @@
     
     static void
     buildRpcRequest_Process(RpcRequest::Builder &b,
-                             const Vamp::HostExt::ProcessRequest &pr,
-                             const PluginHandleMapper &pmapper) {
+                            const Vamp::HostExt::ProcessRequest &pr,
+                            const PluginHandleMapper &pmapper) {
         auto u = b.getRequest().initProcess();
         buildProcessRequest(u, pr, pmapper);
     }
     
     static void
     buildRpcResponse_Process(RpcResponse::Builder &b,
-                              const Vamp::HostExt::ProcessResponse &pr,
-                              const PluginHandleMapper &pmapper) {
+                             const Vamp::HostExt::ProcessResponse &pr,
+                             const PluginHandleMapper &pmapper) {
 
         auto u = b.getResponse().initProcess();
         buildProcessResponse(u, pr, pmapper);
@@ -789,8 +791,8 @@
     
     static void
     buildRpcRequest_Finish(RpcRequest::Builder &b,
-                            const Vamp::HostExt::FinishRequest &req,
-                            const PluginHandleMapper &pmapper) {
+                           const Vamp::HostExt::FinishRequest &req,
+                           const PluginHandleMapper &pmapper) {
 
         auto u = b.getRequest().initFinish();
         u.setHandle(pmapper.pluginToHandle(req.plugin));
@@ -798,8 +800,8 @@
     
     static void
     buildRpcResponse_Finish(RpcResponse::Builder &b,
-                             const Vamp::HostExt::ProcessResponse &pr,
-                             const PluginHandleMapper &pmapper) {
+                            const Vamp::HostExt::ProcessResponse &pr,
+                            const PluginHandleMapper &pmapper) {
 
         auto u = b.getResponse().initFinish();
         buildFinishResponse(u, pr, pmapper);
@@ -807,8 +809,8 @@
 
     static void
     buildRpcResponse_Error(RpcResponse::Builder &b,
-                            const std::string &errorText,
-                            RRType responseType)
+                           const std::string &errorText,
+                           RRType responseType)
     {
         std::string type;
 
@@ -834,8 +836,8 @@
 
     static void
     buildRpcResponse_Exception(RpcResponse::Builder &b,
-                                const std::exception &e,
-                                RRType responseType)
+                               const std::exception &e,
+                               RRType responseType)
     {
         return buildRpcResponse_Error(b, e.what(), responseType);
     }
@@ -896,7 +898,7 @@
 
     static void
     readRpcResponse_List(Vamp::HostExt::ListResponse &resp,
-                          const RpcResponse::Reader &r) {
+                         const RpcResponse::Reader &r) {
         if (getRequestResponseType(r) != RRType::List) {
             throw std::logic_error("not a list response");
         }
@@ -911,7 +913,7 @@
     
     static void
     readRpcRequest_Load(Vamp::HostExt::LoadRequest &req,
-                         const RpcRequest::Reader &r) {
+                        const RpcRequest::Reader &r) {
         if (getRequestResponseType(r) != RRType::Load) {
             throw std::logic_error("not a load request");
         }
@@ -931,8 +933,8 @@
     
     static void
     readRpcRequest_Configure(Vamp::HostExt::ConfigurationRequest &req,
-                              const RpcRequest::Reader &r,
-                              const PluginHandleMapper &pmapper) {
+                             const RpcRequest::Reader &r,
+                             const PluginHandleMapper &pmapper) {
         if (getRequestResponseType(r) != RRType::Configure) {
             throw std::logic_error("not a configuration request");
         }
@@ -941,8 +943,8 @@
 
     static void
     readRpcResponse_Configure(Vamp::HostExt::ConfigurationResponse &resp,
-                               const RpcResponse::Reader &r,
-                               const PluginHandleMapper &pmapper) {
+                              const RpcResponse::Reader &r,
+                              const PluginHandleMapper &pmapper) {
         if (getRequestResponseType(r) != RRType::Configure) {
             throw std::logic_error("not a configuration response");
         }
@@ -954,8 +956,8 @@
     
     static void
     readRpcRequest_Process(Vamp::HostExt::ProcessRequest &req,
-                            const RpcRequest::Reader &r,
-                            const PluginHandleMapper &pmapper) {
+                           const RpcRequest::Reader &r,
+                           const PluginHandleMapper &pmapper) {
         if (getRequestResponseType(r) != RRType::Process) {
             throw std::logic_error("not a process request");
         }
@@ -964,8 +966,8 @@
 
     static void
     readRpcResponse_Process(Vamp::HostExt::ProcessResponse &resp,
-                             const RpcResponse::Reader &r,
-                             const PluginHandleMapper &pmapper) {
+                            const RpcResponse::Reader &r,
+                            const PluginHandleMapper &pmapper) {
         if (getRequestResponseType(r) != RRType::Process) {
             throw std::logic_error("not a process response");
         }
@@ -975,8 +977,8 @@
     
     static void
     readRpcRequest_Finish(Vamp::HostExt::FinishRequest &req,
-                           const RpcRequest::Reader &r,
-                           const PluginHandleMapper &pmapper) {
+                          const RpcRequest::Reader &r,
+                          const PluginHandleMapper &pmapper) {
         if (getRequestResponseType(r) != RRType::Finish) {
             throw std::logic_error("not a finish request");
         }
@@ -986,8 +988,8 @@
 
     static void
     readRpcResponse_Finish(Vamp::HostExt::ProcessResponse &resp,
-                            const RpcResponse::Reader &r,
-                            const PluginHandleMapper &pmapper) {
+                           const RpcResponse::Reader &r,
+                           const PluginHandleMapper &pmapper) {
         if (getRequestResponseType(r) != RRType::Finish) {
             throw std::logic_error("not a finish response");
         }
--- a/vamp-client/Makefile	Tue Oct 11 14:38:04 2016 +0100
+++ b/vamp-client/Makefile	Tue Oct 11 15:49:28 2016 +0100
@@ -2,6 +2,6 @@
 VAMPSDK_DIR	:= ../../vamp-plugin-sdk
 PIPER_DIR	:= ../../piper
 
-CXXFLAGS = -I$(VAMPSDK_DIR)
+CXXFLAGS = -I$(VAMPSDK_DIR) -I..
 
 client:	client.cpp
--- a/vamp-client/client.cpp	Tue Oct 11 14:38:04 2016 +0100
+++ b/vamp-client/client.cpp	Tue Oct 11 15:49:28 2016 +0100
@@ -1,3 +1,46 @@
 
 #include "stub.h"
 
+#include "vamp-capnp/VampnProto.h"
+
+#include "vamp-support/AssignedPluginHandleMapper.h"
+
+namespace piper {
+
+class PiperClient : public PiperClientBase
+{
+public:
+    
+    virtual
+    Vamp::Plugin::OutputList
+    configure(PiperStubPlugin *plugin,
+              Vamp::HostExt::PluginConfiguration config) {
+
+        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);
+
+        //!!! now what?
+    }
+    
+    
+    virtual
+    Vamp::Plugin::FeatureSet
+    process(PiperStubPlugin *plugin,
+            const float *const *inputBuffers,
+            Vamp::RealTime timestamp) = 0;
+
+    virtual Vamp::Plugin::FeatureSet
+    finish(PiperStubPlugin *plugin) = 0;
+
+private:
+    AssignedPluginHandleMapper m_mapper;
+};
+    
+}
+
--- a/vamp-client/stub.h	Tue Oct 11 14:38:04 2016 +0100
+++ b/vamp-client/stub.h	Tue Oct 11 15:49:28 2016 +0100
@@ -8,24 +8,24 @@
 
 namespace piper { //!!! should be something else
 
-typedef int32_t PiperPluginHandle;
+class PiperStubPlugin;
 
 class PiperClientBase
 {
 public:
     virtual
     Vamp::Plugin::OutputList
-    configure(PiperPluginHandle handle,
+    configure(PiperStubPlugin *plugin,
               Vamp::HostExt::PluginConfiguration config) = 0;
     
     virtual
     Vamp::Plugin::FeatureSet
-    process(PiperPluginHandle handle,
+    process(PiperStubPlugin *plugin,
             const float *const *inputBuffers,
             Vamp::RealTime timestamp) = 0;
 
     virtual Vamp::Plugin::FeatureSet
-    finish(PiperPluginHandle handle) = 0;
+    finish(PiperStubPlugin *plugin) = 0;
 };
 
 class PiperStubPlugin : public Vamp::Plugin
@@ -36,13 +36,11 @@
     
 public:
     PiperStubPlugin(PiperClientBase *client,
-                    PiperPluginHandle handle,
                     float inputSampleRate,
                     Vamp::HostExt::PluginStaticData psd,
                     Vamp::HostExt::PluginConfiguration defaultConfig) :
         Plugin(inputSampleRate),
         m_client(client),
-        m_handle(handle),
         m_state(Loaded),
         m_psd(psd),
         m_defaultConfig(defaultConfig),
@@ -51,8 +49,7 @@
 
     virtual ~PiperStubPlugin() {
         if (m_state != Finished) {
-            (void)m_client->finish(m_handle);
-            m_state = Finished;
+            std::cerr << "WARNING: PiperStubPlugin destroyed without finish() call, may be a server-side resource leak" << std::endl;
         }
     }
 
@@ -126,7 +123,7 @@
         m_config.stepSize = stepSize;
         m_config.blockSize = blockSize;
 
-        m_outputs = m_client->configure(m_handle, m_config);
+        m_outputs = m_client->configure(this, m_config);
 
         if (!m_outputs.empty()) {
             m_state = Configured;
@@ -192,7 +189,7 @@
             throw std::logic_error("Plugin has already been disposed of");
         }
 
-        return m_client->process(m_handle, inputBuffers, timestamp);
+        return m_client->process(this, inputBuffers, timestamp);
     }
 
     virtual FeatureSet getRemainingFeatures() {
@@ -206,12 +203,11 @@
 
         m_state = Finished;
 
-        return m_client->finish(m_handle);
+        return m_client->finish(this);
     }
     
 private:
     PiperClientBase *m_client;
-    PiperPluginHandle m_handle;
     State m_state;
     Vamp::HostExt::PluginStaticData m_psd;
     OutputList m_outputs;
--- a/vamp-json/VampJson.h	Tue Oct 11 14:38:04 2016 +0100
+++ b/vamp-json/VampJson.h	Tue Oct 11 15:49:28 2016 +0100
@@ -44,6 +44,9 @@
 
 #include <vamp-hostsdk/Plugin.h>
 #include <vamp-hostsdk/PluginLoader.h>
+#include <vamp-hostsdk/PluginStaticData.h>
+#include <vamp-hostsdk/PluginConfiguration.h>
+#include <vamp-hostsdk/RequestResponse.h>
 
 #include "vamp-support/PluginHandleMapper.h"
 #include "vamp-support/PluginOutputIdMapper.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vamp-support/AssignedPluginHandleMapper.h	Tue Oct 11 15:49:28 2016 +0100
@@ -0,0 +1,147 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Piper C++
+
+    Centre for Digital Music, Queen Mary, University of London.
+    Copyright 2006-2016 Chris Cannam and QMUL.
+  
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use, copy,
+    modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+    Except as contained in this notice, the names of the Centre for
+    Digital Music; Queen Mary, University of London; and Chris Cannam
+    shall not be used in advertising or otherwise to promote the sale,
+    use or other dealings in this Software without prior written
+    authorization.
+*/
+
+#ifndef PIPER_ASSIGNED_PLUGIN_HANDLE_MAPPER_H
+#define PIPER_ASSIGNED_PLUGIN_HANDLE_MAPPER_H
+
+#include "PluginHandleMapper.h"
+#include "PluginOutputIdMapper.h"
+#include "DefaultPluginOutputIdMapper.h"
+
+#include <set>
+#include <map>
+#include <iostream>
+
+namespace piper {
+
+class AssignedPluginHandleMapper : public PluginHandleMapper
+{
+public:
+    AssignedPluginHandleMapper() { }
+
+    void addPlugin(Vamp::Plugin *p, Handle h) {
+        if (!p) return;
+	if (m_rplugins.find(p) == m_rplugins.end()) {
+            if (m_plugins.find(h) != m_plugins.end()) {
+                std::cerr << "ERROR: Duplicate plugin handle " << h
+                          << " for plugin " << p << " (already used for plugin "
+                          << m_plugins[h] << ")" << std::endl;
+                throw std::logic_error("Duplicate plugin handle");
+            }
+	    m_plugins[h] = p;
+	    m_rplugins[p] = h;
+            m_outputMappers[h] =
+                std::make_shared<DefaultPluginOutputIdMapper>(p);
+	}
+    }
+
+    void removePlugin(Handle h) {
+	if (m_plugins.find(h) == m_plugins.end()) return;
+	Vamp::Plugin *p = m_plugins[h];
+        m_outputMappers.erase(h);
+	m_plugins.erase(h);
+	if (isConfigured(h)) {
+	    m_configuredPlugins.erase(h);
+	    m_channelCounts.erase(h);
+	}
+	m_rplugins.erase(p);
+    }
+    
+    Handle pluginToHandle(Vamp::Plugin *p) const noexcept {
+	if (m_rplugins.find(p) == m_rplugins.end()) {
+            return INVALID_HANDLE;
+	}
+	return m_rplugins.at(p);
+    }
+    
+    Vamp::Plugin *handleToPlugin(Handle h) const noexcept {
+	if (m_plugins.find(h) == m_plugins.end()) {
+            return nullptr;
+	}
+	return m_plugins.at(h);
+    }
+
+    const std::shared_ptr<PluginOutputIdMapper> pluginToOutputIdMapper
+    (Vamp::Plugin *p) const noexcept {
+        return handleToOutputIdMapper(pluginToHandle(p));
+    }
+
+    const std::shared_ptr<PluginOutputIdMapper> handleToOutputIdMapper
+    (Handle h) const noexcept {
+	if (h != INVALID_HANDLE &&
+            m_outputMappers.find(h) != m_outputMappers.end()) {
+            return m_outputMappers.at(h);
+        } else {
+	    return {};
+	}
+    }
+
+    bool isConfigured(Handle h) const noexcept {
+        if (h == INVALID_HANDLE) return false;
+	return m_configuredPlugins.find(h) != m_configuredPlugins.end();
+    }
+
+    void markConfigured(Handle h, int channelCount, int blockSize) {
+        if (h == INVALID_HANDLE) return;
+	m_configuredPlugins.insert(h);
+	m_channelCounts[h] = channelCount;
+	m_blockSizes[h] = blockSize;
+    }
+
+    int getChannelCount(Handle h) const noexcept {
+	if (m_channelCounts.find(h) == m_channelCounts.end()) {
+	    return 0;
+	}
+	return m_channelCounts.at(h);
+    }
+
+    int getBlockSize(Handle h) const noexcept {
+	if (m_blockSizes.find(h) == m_blockSizes.end()) {
+            return 0;
+	}
+	return m_blockSizes.at(h);
+    }
+    
+private:
+    std::map<Handle, Vamp::Plugin *> m_plugins;
+    std::map<Vamp::Plugin *, Handle> m_rplugins;
+    std::set<Handle> m_configuredPlugins;
+    std::map<Handle, int> m_channelCounts;
+    std::map<Handle, int> m_blockSizes;
+    std::map<Handle, std::shared_ptr<PluginOutputIdMapper>> m_outputMappers;
+};
+
+}
+
+#endif
--- a/vamp-support/CountingPluginHandleMapper.h	Tue Oct 11 14:38:04 2016 +0100
+++ b/vamp-support/CountingPluginHandleMapper.h	Tue Oct 11 15:49:28 2016 +0100
@@ -37,7 +37,7 @@
 
 #include "PluginHandleMapper.h"
 #include "PluginOutputIdMapper.h"
-#include "DefaultPluginOutputIdMapper.h"
+#include "AssignedPluginHandleMapper.h"
 
 #include <set>
 #include <map>
@@ -50,91 +50,51 @@
     CountingPluginHandleMapper() : m_nextHandle(1) { }
 
     void addPlugin(Vamp::Plugin *p) {
-        if (!p) return;
-	if (m_rplugins.find(p) == m_rplugins.end()) {
-	    Handle h = m_nextHandle++;
-	    m_plugins[h] = p;
-	    m_rplugins[p] = h;
-            m_outputMappers[h] =
-                std::make_shared<DefaultPluginOutputIdMapper>(p);
-	}
+        Handle h = m_nextHandle++;
+        m_sub.addPlugin(p, h);
     }
 
     void removePlugin(Handle h) {
-	if (m_plugins.find(h) == m_plugins.end()) return;
-	Vamp::Plugin *p = m_plugins[h];
-        m_outputMappers.erase(h);
-	m_plugins.erase(h);
-	if (isConfigured(h)) {
-	    m_configuredPlugins.erase(h);
-	    m_channelCounts.erase(h);
-	}
-	m_rplugins.erase(p);
+        m_sub.removePlugin(h);
     }
     
     Handle pluginToHandle(Vamp::Plugin *p) const noexcept {
-	if (m_rplugins.find(p) == m_rplugins.end()) {
-            return INVALID_HANDLE;
-	}
-	return m_rplugins.at(p);
+        return m_sub.pluginToHandle(p);
     }
     
     Vamp::Plugin *handleToPlugin(Handle h) const noexcept {
-	if (m_plugins.find(h) == m_plugins.end()) {
-            return nullptr;
-	}
-	return m_plugins.at(h);
+        return m_sub.handleToPlugin(h);
     }
 
     const std::shared_ptr<PluginOutputIdMapper> pluginToOutputIdMapper
     (Vamp::Plugin *p) const noexcept {
-        return handleToOutputIdMapper(pluginToHandle(p));
+        return m_sub.pluginToOutputIdMapper(p);
     }
 
     const std::shared_ptr<PluginOutputIdMapper> handleToOutputIdMapper
     (Handle h) const noexcept {
-	if (h != INVALID_HANDLE &&
-            m_outputMappers.find(h) != m_outputMappers.end()) {
-            return m_outputMappers.at(h);
-        } else {
-	    return {};
-	}
+        return m_sub.handleToOutputIdMapper(h);
     }
 
     bool isConfigured(Handle h) const noexcept {
-        if (h == INVALID_HANDLE) return false;
-	return m_configuredPlugins.find(h) != m_configuredPlugins.end();
+        return m_sub.isConfigured(h);
     }
 
     void markConfigured(Handle h, int channelCount, int blockSize) {
-        if (h == INVALID_HANDLE) return;
-	m_configuredPlugins.insert(h);
-	m_channelCounts[h] = channelCount;
-	m_blockSizes[h] = blockSize;
+        m_sub.markConfigured(h, channelCount, blockSize);
     }
 
     int getChannelCount(Handle h) const noexcept {
-	if (m_channelCounts.find(h) == m_channelCounts.end()) {
-	    return 0;
-	}
-	return m_channelCounts.at(h);
+        return m_sub.getChannelCount(h);
     }
 
     int getBlockSize(Handle h) const noexcept {
-	if (m_blockSizes.find(h) == m_blockSizes.end()) {
-            return 0;
-	}
-	return m_blockSizes.at(h);
+        return m_sub.getBlockSize(h);
     }
     
 private:
     Handle m_nextHandle; // NB plugin handle type must fit in JSON number
-    std::map<Handle, Vamp::Plugin *> m_plugins;
-    std::map<Vamp::Plugin *, Handle> m_rplugins;
-    std::set<Handle> m_configuredPlugins;
-    std::map<Handle, int> m_channelCounts;
-    std::map<Handle, int> m_blockSizes;
-    std::map<Handle, std::shared_ptr<PluginOutputIdMapper>> m_outputMappers;
+    AssignedPluginHandleMapper m_sub;
 };
 
 }