changeset 31:b376ab0ce003

Begin server
author Chris Cannam <c.cannam@qmul.ac.uk>
date Tue, 24 May 2016 16:30:01 +0100
parents eb679afcd1bb
children 2d97883d20df
files Makefile bits/PreservingPluginHandleMapper.h bits/RequestOrResponse.h utilities/vampipe-convert.cpp utilities/vampipe-server.cpp
diffstat 5 files changed, 287 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Tue May 24 15:38:50 2016 +0100
+++ b/Makefile	Tue May 24 16:30:01 2016 +0100
@@ -3,11 +3,14 @@
 INCFLAGS	:= -Ivamp-plugin-sdk -Ijson -Icapnproto -I.
 LDFLAGS		:= -Lvamp-plugin-sdk -Wl,-Bstatic -lvamp-hostsdk -Wl,-Bdynamic -lcapnp -lkj -ldl
 
-all:	bin/vamp-json-cli bin/vamp-json-to-capnp bin/vampipe-convert
+all:	bin/vamp-json-cli bin/vamp-json-to-capnp bin/vampipe-convert bin/vampipe-server
 
 bin/vampipe-convert: o/vampipe-convert.o o/json11.o o/vamp.capnp.o
 	c++ $(CXXFLAGS) $^ -o $@ $(LDFLAGS)
 
+bin/vampipe-server: o/vampipe-server.o o/vamp.capnp.o
+	c++ $(CXXFLAGS) $^ -o $@ $(LDFLAGS)
+
 bin/vamp-json-to-capnp:	o/json-to-capnp.o o/json11.o
 	c++ $(CXXFLAGS) $^ -o $@ $(LDFLAGS)
 
@@ -26,6 +29,9 @@
 o/vampipe-convert.o:	utilities/vampipe-convert.cpp capnproto/vamp.capnp.h capnproto/VampnProto.h json/VampJson.h
 	c++ $(CXXFLAGS) $(INCFLAGS) -c $< -o $@
 
+o/vampipe-server.o:	utilities/vampipe-server.cpp capnproto/vamp.capnp.h capnproto/VampnProto.h 
+	c++ $(CXXFLAGS) $(INCFLAGS) -c $< -o $@
+
 o/json-to-capnp.o:	utilities/json-to-capnp.cpp capnproto/vamp.capnp.h capnproto/VampnProto.h json/VampJson.h
 	c++ $(CXXFLAGS) $(INCFLAGS) -c $< -o $@
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bits/PreservingPluginHandleMapper.h	Tue May 24 16:30:01 2016 +0100
@@ -0,0 +1,65 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Vampipe
+
+    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 VAMPIPE_PRESERVING_PLUGIN_HANDLE_MAPPER_H
+#define VAMPIPE_PRESERVING_PLUGIN_HANDLE_MAPPER_H
+
+#include "PluginHandleMapper.h"
+
+namespace vampipe {
+
+class PreservingPluginHandleMapper : public PluginHandleMapper
+{
+public:
+    PreservingPluginHandleMapper() : m_handle(0), m_plugin(0) { }
+
+    virtual int32_t pluginToHandle(Vamp::Plugin *p) {
+	if (p == m_plugin) return m_handle;
+	else throw NotFound();
+    }
+
+    virtual Vamp::Plugin *handleToPlugin(int32_t h) {
+	m_handle = h;
+	m_plugin = reinterpret_cast<Vamp::Plugin *>(h);
+	return m_plugin;
+    }
+
+private:
+    int32_t m_handle;
+    Vamp::Plugin *m_plugin;
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bits/RequestOrResponse.h	Tue May 24 16:30:01 2016 +0100
@@ -0,0 +1,82 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Vampipe
+
+    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 VAMPIPE_REQUEST_OR_RESPONSE_H
+#define VAMPIPE_REQUEST_OR_RESPONSE_H
+
+#include "PreservingPluginHandleMapper.h"
+#include "RequestResponseType.h"
+
+#include <vamp-hostsdk/PluginStaticData.h>
+#include <vamp-hostsdk/RequestResponse.h>
+
+#include <string>
+#include <vector>
+
+namespace vampipe {
+
+class RequestOrResponse
+{
+public:
+    enum Direction {
+	Request, Response
+    };
+    
+    RequestOrResponse() : // nothing by default
+	direction(Request),
+	type(RRType::NotValid),
+	success(false),
+	finishPlugin(0) { }
+
+    Direction direction;
+    RRType type;
+    bool success;
+    std::string errorText;
+
+    PreservingPluginHandleMapper mapper;
+
+    std::vector<Vamp::HostExt::PluginStaticData> listResponse;
+    Vamp::HostExt::LoadRequest loadRequest;
+    Vamp::HostExt::LoadResponse loadResponse;
+    Vamp::HostExt::ConfigurationRequest configurationRequest;
+    Vamp::HostExt::ConfigurationResponse configurationResponse;
+    Vamp::HostExt::ProcessRequest processRequest;
+    Vamp::HostExt::ProcessResponse processResponse;
+    Vamp::Plugin *finishPlugin;
+    Vamp::HostExt::ProcessResponse finishResponse;
+};
+
+}
+
+#endif
--- a/utilities/vampipe-convert.cpp	Tue May 24 15:38:50 2016 +0100
+++ b/utilities/vampipe-convert.cpp	Tue May 24 16:30:01 2016 +0100
@@ -2,6 +2,8 @@
 #include "VampJson.h"
 #include "VampnProto.h"
 
+#include "bits/RequestOrResponse.h"
+
 #include <iostream>
 #include <sstream>
 #include <stdexcept>
@@ -10,32 +12,6 @@
 using namespace json11;
 using namespace vampipe;
 
-// Accepting JSON objects with two fields, "type" and "content". The
-// "type" string corresponds to the JSON schema filename
-// (e.g. "outputdescriptor") and the "content" is the JSON object
-// encoded with that schema.
-
-class PreservingPluginHandleMapper : public PluginHandleMapper
-{
-public:
-    PreservingPluginHandleMapper() : m_handle(0), m_plugin(0) { }
-
-    virtual int32_t pluginToHandle(Vamp::Plugin *p) {
-	if (p == m_plugin) return m_handle;
-	else throw NotFound();
-    }
-
-    virtual Vamp::Plugin *handleToPlugin(int32_t h) {
-	m_handle = h;
-	m_plugin = reinterpret_cast<Vamp::Plugin *>(h);
-	return m_plugin;
-    }
-
-private:
-    int32_t m_handle;
-    Vamp::Plugin *m_plugin;
-};
-
 void usage()
 {
     string myname = "vampipe-convert";
@@ -56,37 +32,6 @@
     exit(2);
 }
 
-class RequestOrResponse
-{
-public:
-    enum Direction {
-	Request, Response
-    };
-    
-    RequestOrResponse() : // nothing by default
-	direction(Request),
-	type(RRType::NotValid),
-	success(false),
-	finishPlugin(0) { }
-
-    Direction direction;
-    RRType type;
-    bool success;
-    string errorText;
-
-    PreservingPluginHandleMapper mapper;
-
-    vector<Vamp::HostExt::PluginStaticData> listResponse;
-    Vamp::HostExt::LoadRequest loadRequest;
-    Vamp::HostExt::LoadResponse loadResponse;
-    Vamp::HostExt::ConfigurationRequest configurationRequest;
-    Vamp::HostExt::ConfigurationResponse configurationResponse;
-    Vamp::HostExt::ProcessRequest processRequest;
-    Vamp::HostExt::ProcessResponse processResponse;
-    Vamp::Plugin *finishPlugin;
-    Vamp::HostExt::ProcessResponse finishResponse;
-};
-
 Json
 convertRequestJson(string input)
 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utilities/vampipe-server.cpp	Tue May 24 16:30:01 2016 +0100
@@ -0,0 +1,131 @@
+
+#include "VampnProto.h"
+
+#include "bits/RequestOrResponse.h"
+
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+
+using namespace std;
+using namespace vampipe;
+
+void usage()
+{
+    string myname = "vampipe-server";
+    cerr << "\n" << myname <<
+	": Load and run Vamp plugins in response to messages from stdin\n\n"
+	"    Usage: " << myname << "\n\n"
+	"Expects Vamp request messages in Cap'n Proto packed format on stdin,\n"
+	"and writes Vamp response messages in the same format to stdout.\n\n";
+
+    exit(2);
+}
+
+RequestOrResponse
+readRequestCapnp()
+{
+    RequestOrResponse rr;
+    rr.direction = RequestOrResponse::Request;
+
+    ::capnp::PackedFdMessageReader message(0); // stdin
+    VampRequest::Reader reader = message.getRoot<VampRequest>();
+    
+    rr.type = VampnProto::getRequestResponseType(reader);
+
+    switch (rr.type) {
+
+    case RRType::List:
+	VampnProto::readVampRequest_List(reader); // type check only
+	break;
+    case RRType::Load:
+	VampnProto::readVampRequest_Load(rr.loadRequest, reader);
+	break;
+    case RRType::Configure:
+	VampnProto::readVampRequest_Configure(rr.configurationRequest, reader,
+					      rr.mapper);
+	break;
+    case RRType::Process:
+	VampnProto::readVampRequest_Process(rr.processRequest, reader,
+					    rr.mapper);
+	break;
+    case RRType::Finish:
+	VampnProto::readVampRequest_Finish(rr.finishPlugin, reader,
+					   rr.mapper);
+	break;
+    case RRType::NotValid:
+	break;
+    }
+
+    return rr;
+}
+
+void
+writeResponseCapnp(RequestOrResponse &rr)
+{
+    ::capnp::MallocMessageBuilder message;
+    VampResponse::Builder builder = message.initRoot<VampResponse>();
+
+    switch (rr.type) {
+
+    case RRType::List:
+	VampnProto::buildVampResponse_List(builder, "", rr.listResponse);
+	break;
+    case RRType::Load:
+	VampnProto::buildVampResponse_Load(builder, rr.loadResponse, rr.mapper);
+	break;
+    case RRType::Configure:
+	VampnProto::buildVampResponse_Configure(builder, rr.configurationResponse);
+	break;
+    case RRType::Process:
+	VampnProto::buildVampResponse_Process(builder, rr.processResponse);
+	break;
+    case RRType::Finish:
+	VampnProto::buildVampResponse_Finish(builder, rr.finishResponse);
+	break;
+    case RRType::NotValid:
+	break;
+    }
+
+    writePackedMessageToFd(1, message);
+}
+
+RequestOrResponse
+processRequest(const RequestOrResponse &request)
+{
+    RequestOrResponse response;
+    response.direction = RequestOrResponse::Response;
+    //!!! DO THE WORK!
+    return response;
+}
+
+int main(int argc, char **argv)
+{
+    if (argc != 1) {
+	usage();
+    }
+
+    while (true) {
+
+	try {
+
+	    RequestOrResponse request = readRequestCapnp();
+
+	    // NotValid without an exception indicates EOF:
+
+	    //!!! not yet it doesn't -- have to figure out how to
+	    //!!! handle this with capnp
+	    if (request.type == RRType::NotValid) break;
+
+	    RequestOrResponse response = processRequest(request);
+	    
+	    writeResponseCapnp(response);
+	    
+	} catch (std::exception &e) {
+	    cerr << "Error: " << e.what() << endl;
+	    exit(1);
+	}
+    }
+
+    exit(0);
+}