changeset 31:f565f4b5cbaa

Pull out plugin object implementation into separate source file
author Chris Cannam
date Wed, 26 Nov 2014 11:12:00 +0000
parents e1e54546d5fd
children d5aba4c3c229
files Makefile PyPluginObject.cpp PyPluginObject.h vampyhost.cpp vampyhost.h
diffstat 4 files changed, 497 insertions(+), 426 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Nov 26 10:57:31 2014 +0000
+++ b/Makefile	Wed Nov 26 11:12:00 2014 +0000
@@ -7,7 +7,7 @@
 
 LDFLAGS		:= -shared -Wl,-Bstatic -lvamp-hostsdk -Wl,-Bdynamic -Wl,-z,defs -lpython2.7 -ldl
 
-OBJECTS	:= PyRealTime.o VectorConversion.o vampyhost.o
+OBJECTS	:= PyPluginObject.o PyRealTime.o VectorConversion.o vampyhost.o
 
 all: vampyhost.so
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PyPluginObject.cpp	Wed Nov 26 11:12:00 2014 +0000
@@ -0,0 +1,409 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    VampyHost
+
+    Use Vamp audio analysis plugins in Python
+
+    Gyorgy Fazekas and Chris Cannam
+    Centre for Digital Music, Queen Mary, University of London
+    Copyright 2008-2014 Queen Mary, University of London
+  
+    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 the authors
+    shall not be used in advertising or otherwise to promote the sale,
+    use or other dealings in this Software without prior written
+    authorization.
+*/
+
+#include "PyPluginObject.h"
+
+// define a unique API pointer 
+#define PY_ARRAY_UNIQUE_SYMBOL VAMPYHOST_ARRAY_API
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+#define NO_IMPORT_ARRAY
+#include "numpy/arrayobject.h"
+
+#include "VectorConversion.h"
+#include "PyRealTime.h"
+
+#include <string>
+#include <vector>
+
+using namespace std;
+using namespace Vamp;
+
+static void
+PyPluginObject_dealloc(PyPluginObject *self)
+{
+    cerr << "PyPluginObject_dealloc" << endl;
+    delete self->plugin;
+    PyObject_Del(self);
+}
+
+PyDoc_STRVAR(xx_foo_doc, "Some description"); //!!!
+
+//!!! todo: conv errors
+
+static
+PyPluginObject *
+getPluginObject(PyObject *pyPluginHandle)
+{
+    cerr << "getPluginObject" << endl;
+
+    PyPluginObject *pd = 0;
+    if (PyPlugin_Check(pyPluginHandle)) {
+        pd = (PyPluginObject *)pyPluginHandle;
+    }
+    if (!pd || !pd->plugin) {
+        PyErr_SetString(PyExc_AttributeError,
+			"Invalid or already deleted plugin handle.");
+        return 0;
+    } else {
+        return pd;
+    }
+}
+
+PyObject *
+PyPluginObject_From_Plugin(Plugin *plugin)
+{
+    PyPluginObject *pd = 
+        (PyPluginObject *)PyType_GenericAlloc(&Plugin_Type, 0);
+    pd->plugin = plugin;
+    pd->isInitialised = false;
+    pd->channels = 0;
+    pd->blockSize = 0;
+    pd->stepSize = 0;
+    return (PyObject *)pd;
+}
+
+static PyObject *
+vampyhost_initialise(PyObject *self, PyObject *args)
+{
+    cerr << "vampyhost_initialise" << endl;
+    
+    size_t channels, blockSize, stepSize;
+
+    if (!PyArg_ParseTuple (args, "nnn",
+			   (size_t) &channels,
+			   (size_t) &stepSize,
+			   (size_t) &blockSize)) {
+	PyErr_SetString(PyExc_TypeError,
+			"initialise() takes channel count, step size, and block size arguments");
+	return 0;
+    }
+
+    PyPluginObject *pd = getPluginObject(self);
+    if (!pd) return 0;
+
+    pd->channels = channels;
+    pd->stepSize = stepSize;
+    pd->blockSize = blockSize;
+
+    if (!pd->plugin->initialise(channels, stepSize, blockSize)) {
+        cerr << "Failed to initialise native plugin adapter with channels = " << channels << ", stepSize = " << stepSize << ", blockSize = " << blockSize << " and ADAPT_ALL_SAFE set" << endl;
+	PyErr_SetString(PyExc_TypeError,
+			"Plugin initialization failed");
+	return 0;
+    }
+
+    pd->isInitialised = true;
+
+    return Py_True;
+}
+
+static PyObject *
+vampyhost_reset(PyObject *self, PyObject *)
+{
+    cerr << "vampyhost_reset" << endl;
+    
+    PyPluginObject *pd = getPluginObject(self);
+    if (!pd) return 0;
+
+    if (!pd->isInitialised) {
+        PyErr_SetString(PyExc_StandardError,
+                        "Plugin has not been initialised");
+        return 0;
+    }
+        
+    pd->plugin->reset();
+    return Py_True;
+}
+
+static PyObject *
+vampyhost_getParameter(PyObject *self, PyObject *args)
+{
+    cerr << "vampyhost_getParameter" << endl;
+
+    PyObject *pyParam;
+
+    if (!PyArg_ParseTuple(args, "S", &pyParam)) {
+	PyErr_SetString(PyExc_TypeError,
+			"getParameter() takes parameter id (string) argument");
+	return 0; }
+
+    PyPluginObject *pd = getPluginObject(self);
+    if (!pd) return 0;
+
+    float value = pd->plugin->getParameter(PyString_AS_STRING(pyParam));
+    return PyFloat_FromDouble(double(value));
+}
+
+static PyObject *
+vampyhost_setParameter(PyObject *self, PyObject *args)
+{
+    cerr << "vampyhost_setParameter" << endl;
+
+    PyObject *pyParam;
+    float value;
+
+    if (!PyArg_ParseTuple(args, "Sf", &pyParam, &value)) {
+	PyErr_SetString(PyExc_TypeError,
+			"setParameter() takes parameter id (string), and value (float) arguments");
+	return 0; }
+
+    PyPluginObject *pd = getPluginObject(self);
+    if (!pd) return 0;
+
+    pd->plugin->setParameter(PyString_AS_STRING(pyParam), value);
+    return Py_True;
+}
+
+static PyObject *
+vampyhost_process(PyObject *self, PyObject *args)
+{
+    cerr << "vampyhost_process" << endl;
+
+    PyObject *pyBuffer;
+    PyObject *pyRealTime;
+
+    if (!PyArg_ParseTuple(args, "OO",
+			  &pyBuffer,			// Audio data
+			  &pyRealTime)) {		// TimeStamp
+	PyErr_SetString(PyExc_TypeError,
+			"process() takes plugin handle (object), buffer (2D array of channels * samples floats) and timestamp (RealTime) arguments");
+	return 0; }
+
+    if (!PyRealTime_Check(pyRealTime)) {
+	PyErr_SetString(PyExc_TypeError,"Valid timestamp required.");
+	return 0; }
+
+    if (!PyList_Check(pyBuffer)) {
+	PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input.");
+        return 0;
+    }
+
+    PyPluginObject *pd = getPluginObject(self);
+    if (!pd) return 0;
+
+    if (!pd->isInitialised) {
+	PyErr_SetString(PyExc_StandardError,
+			"Plugin has not been initialised.");
+	return 0;
+    }
+
+    int channels =  pd->channels;
+
+    if (PyList_GET_SIZE(pyBuffer) != channels) {
+        cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << endl;
+	PyErr_SetString(PyExc_TypeError, "Wrong number of channels");
+        return 0;
+    }
+
+    float **inbuf = new float *[channels];
+
+    VectorConversion typeConv;
+
+    cerr << "here!"  << endl;
+    
+    vector<vector<float> > data;
+    for (int c = 0; c < channels; ++c) {
+        PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c);
+        data.push_back(typeConv.PyValue_To_FloatVector(cbuf));
+    }
+    
+    for (int c = 0; c < channels; ++c) {
+        if (data[c].size() != pd->blockSize) {
+            cerr << "Wrong number of samples on channel " << c << ": expected " << pd->blockSize << " (plugin's block size), got " << data[c].size() << endl;
+            PyErr_SetString(PyExc_TypeError, "Wrong number of samples");
+            return 0;
+        }
+        inbuf[c] = &data[c][0];
+    }
+
+    cerr << "no, here!"  << endl;
+
+    RealTime timeStamp = *PyRealTime_AsRealTime(pyRealTime);
+
+    cerr << "no no, here!"  << endl;
+
+    Plugin::FeatureSet fs = pd->plugin->process(inbuf, timeStamp);
+
+    delete[] inbuf;
+
+    cerr << "no no no, here!"  << endl;
+    
+    VectorConversion conv;
+    
+    PyObject *pyFs = PyDict_New();
+
+    for (Plugin::FeatureSet::const_iterator fsi = fs.begin();
+         fsi != fs.end(); ++fsi) {
+
+        int fno = fsi->first;
+        const Plugin::FeatureList &fl = fsi->second;
+
+        if (!fl.empty()) {
+
+            PyObject *pyFl = PyList_New(fl.size());
+
+            for (int fli = 0; fli < (int)fl.size(); ++fli) {
+
+                const Plugin::Feature &f = fl[fli];
+                PyObject *pyF = PyDict_New();
+
+                if (f.hasTimestamp) {
+                    PyDict_SetItemString
+                        (pyF, "timestamp", PyRealTime_FromRealTime(f.timestamp));
+                }
+                if (f.hasDuration) {
+                    PyDict_SetItemString
+                        (pyF, "duration", PyRealTime_FromRealTime(f.duration));
+                }
+
+                PyDict_SetItemString
+                    (pyF, "label", PyString_FromString(f.label.c_str()));
+
+                if (!f.values.empty()) {
+                    PyDict_SetItemString
+                        (pyF, "values", conv.PyArray_From_FloatVector(f.values));
+                }
+
+                PyList_SET_ITEM(pyFl, fli, pyF);
+            }
+
+            PyObject *pyN = PyInt_FromLong(fno);
+            PyDict_SetItem(pyFs, pyN, pyFl);
+        }
+    }
+
+    cerr << "no you fool, here!"  << endl;
+    
+    return pyFs;
+}
+
+static PyObject *
+vampyhost_unload(PyObject *self, PyObject *)
+{
+    cerr << "vampyhost_unloadPlugin" << endl;
+    
+    PyPluginObject *pd = getPluginObject(self);
+    if (!pd) return 0;
+
+    delete pd->plugin;
+    pd->plugin = 0; // This is checked by getPluginObject, so we 
+                    // attempt to avoid repeated calls from blowing up
+
+    return Py_True;
+}
+
+static PyMethodDef PyPluginObject_methods[] =
+{
+    {"getParameter",	vampyhost_getParameter, METH_VARARGS,
+     xx_foo_doc}, //!!! fix all these!
+
+    {"setParameter",	vampyhost_setParameter, METH_VARARGS,
+     xx_foo_doc},
+
+    {"initialise",	vampyhost_initialise, METH_VARARGS,
+     xx_foo_doc},
+
+    {"reset",	vampyhost_reset, METH_NOARGS,
+     xx_foo_doc},
+
+    {"process",	vampyhost_process, METH_VARARGS,
+     xx_foo_doc},
+
+    {"unload", vampyhost_unload, METH_NOARGS,
+     xx_foo_doc},
+    
+    {0, 0}
+};
+
+static int
+PyPluginObject_setattr(PyPluginObject *self, char *name, PyObject *value)
+{
+    return -1;
+}
+
+static PyObject *
+PyPluginObject_getattr(PyPluginObject *self, char *name)
+{
+    return Py_FindMethod(PyPluginObject_methods, (PyObject *)self, name);
+}
+
+/* Doc:: 10.3 Type Objects */ /* static */ 
+PyTypeObject Plugin_Type = 
+{
+    PyObject_HEAD_INIT(NULL)
+    0,						/*ob_size*/
+    "vampyhost.Plugin",				/*tp_name*/
+    sizeof(PyPluginObject),	/*tp_basicsize*/
+    0,		/*tp_itemsize*/
+    (destructor)PyPluginObject_dealloc, /*tp_dealloc*/
+    0,						/*tp_print*/
+    (getattrfunc)PyPluginObject_getattr, /*tp_getattr*/
+    (setattrfunc)PyPluginObject_setattr, /*tp_setattr*/
+    0,						/*tp_compare*/
+    0,			/*tp_repr*/
+    0,	/*tp_as_number*/
+    0,						/*tp_as_sequence*/
+    0,						/*tp_as_mapping*/
+    0,						/*tp_hash*/
+    0,                      /*tp_call*/
+    0,                      /*tp_str*/
+    0,                      /*tp_getattro*/
+    0,                      /*tp_setattro*/
+    0,                      /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+    "Plugin Object",      /*tp_doc*/
+    0,                      /*tp_traverse*/
+    0,                      /*tp_clear*/
+    0,                      /*tp_richcompare*/
+    0,                      /*tp_weaklistoffset*/
+    0,                      /*tp_iter*/
+    0,                      /*tp_iternext*/
+    PyPluginObject_methods,       /*tp_methods*/ 
+    0,                      /*tp_members*/
+    0,                      /*tp_getset*/
+    0,                      /*tp_base*/
+    0,                      /*tp_dict*/
+    0,                      /*tp_descr_get*/
+    0,                      /*tp_descr_set*/
+    0,                      /*tp_dictoffset*/
+    0,                      /*tp_init*/
+    PyType_GenericAlloc,         /*tp_alloc*/
+    0,           /*tp_new*/
+    PyObject_Del,			/*tp_free*/
+    0,                      /*tp_is_gc*/
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PyPluginObject.h	Wed Nov 26 11:12:00 2014 +0000
@@ -0,0 +1,64 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    VampyHost
+
+    Use Vamp audio analysis plugins in Python
+
+    Gyorgy Fazekas and Chris Cannam
+    Centre for Digital Music, Queen Mary, University of London
+    Copyright 2008-2014 Queen Mary, University of London
+  
+    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 the authors
+    shall not be used in advertising or otherwise to promote the sale,
+    use or other dealings in this Software without prior written
+    authorization.
+*/
+
+#ifndef PYPLUGINOBJECT_H
+#define PYPLUGINOBJECT_H
+
+#include <Python.h>
+#include <vamp-hostsdk/Plugin.h>
+
+#include <string>
+
+struct PyPluginObject
+{
+    PyObject_HEAD
+    Vamp::Plugin *plugin;
+    bool isInitialised;
+    size_t channels;
+    size_t blockSize;
+    size_t stepSize;
+};
+
+PyAPI_DATA(PyTypeObject) Plugin_Type;
+#define PyPlugin_Check(v) PyObject_TypeCheck(v, &Plugin_Type)
+
+PyAPI_FUNC(PyObject *)
+PyPluginObject_From_Plugin(Vamp::Plugin *);
+
+#endif
+
+
--- a/vampyhost.cpp	Wed Nov 26 10:57:31 2014 +0000
+++ b/vampyhost.cpp	Wed Nov 26 11:12:00 2014 +0000
@@ -35,8 +35,6 @@
     authorization.
 */
 
-#include "PyRealTime.h"
-
 //include for python extension module: must be first
 #include <Python.h>
 
@@ -45,12 +43,9 @@
 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
 #include "numpy/arrayobject.h"
 
-#include <vampyhost.h>
+#include "PyRealTime.h"
+#include "PyPluginObject.h"
 
-#define HAVE_NUMPY 1 // Required
-
-//includes for vamp host
-#include "vamp-hostsdk/Plugin.h"
 #include "vamp-hostsdk/PluginHostAdapter.h"
 #include "vamp-hostsdk/PluginChannelAdapter.h"
 #include "vamp-hostsdk/PluginInputDomainAdapter.h"
@@ -60,74 +55,18 @@
 #include "PyRealTime.h"
 
 #include <iostream>
-#include <fstream>
-#include <set>
-#include <sndfile.h>
-
-#include <cstring>
-#include <cstdlib>
 #include <string>
 
 #include <cmath>
 
 using namespace std;
 using namespace Vamp;
-
-using Vamp::Plugin;
-using Vamp::PluginHostAdapter;
-using Vamp::RealTime;
-using Vamp::HostExt::PluginLoader;
-
-#define HOST_VERSION "1.1"
-
-// structure for holding plugin instance data
-struct PyPluginObject
-{
-    PyObject_HEAD
-    string *key;
-    Plugin *plugin;
-    float inputSampleRate;
-    bool isInitialised;
-    size_t channels;
-    size_t blockSize;
-    size_t stepSize;
-    static PyPluginObject *create_internal();
-};
-
-PyAPI_DATA(PyTypeObject) Plugin_Type;
-#define PyPlugin_Check(v) PyObject_TypeCheck(v, &Plugin_Type)
-    
-static void
-PyPluginObject_dealloc(PyPluginObject *self)
-{
-    cerr << "PyPluginObject_dealloc" << endl;
-    delete self->key;
-    delete self->plugin;
-    PyObject_Del(self);
-}
+using namespace Vamp::HostExt;
 
 PyDoc_STRVAR(xx_foo_doc, "Some description"); //!!!
 
 //!!! todo: conv errors
 
-PyPluginObject *
-getPluginObject(PyObject *pyPluginHandle)
-{
-    cerr << "getPluginObject" << endl;
-
-    PyPluginObject *pd = 0;
-    if (PyPlugin_Check(pyPluginHandle)) {
-        pd = (PyPluginObject *)pyPluginHandle;
-    }
-    if (!pd || !pd->plugin) {
-        PyErr_SetString(PyExc_AttributeError,
-			"Invalid or already deleted plugin handle.");
-        return 0;
-    } else {
-        return pd;
-    }
-}
-
 static PyObject *
 vampyhost_enumeratePlugins(PyObject *self, PyObject *)
 {
@@ -216,45 +155,29 @@
 {
     cerr << "vampyhost_getOutputList" << endl;
 
-    PyObject *keyOrHandle;
+    PyObject *pyPluginKey;
+
+    if (!PyArg_ParseTuple(args, "S", &pyPluginKey)) {
+	PyErr_SetString(PyExc_TypeError,
+			"getOutputList() takes plugin key (string) argument");
+	return 0; }
+
     Plugin::OutputList outputs;
 
-    if (!PyArg_ParseTuple(args, "O", &keyOrHandle)) {
-	PyErr_SetString(PyExc_TypeError,
-			"getOutputList() takes plugin handle (object) or plugin key (string) argument");
-	return 0;
+    string pluginKey = toPluginKey(pyPluginKey);
+    if (pluginKey == "") return 0;
+
+    PluginLoader *loader = PluginLoader::getInstance();
+
+    Plugin *plugin = loader->loadPlugin
+        (pluginKey, 48000, PluginLoader::ADAPT_ALL_SAFE);
+    if (!plugin) {
+        string pyerr("Failed to load plugin: "); pyerr += pluginKey;
+        PyErr_SetString(PyExc_TypeError,pyerr.c_str());
+        return 0;
     }
 
-    if (PyString_Check(keyOrHandle) ) {
-
-        // we have a plugin key
-
-        string pluginKey = toPluginKey(keyOrHandle);
-        if (pluginKey == "") return 0;
-
-        PluginLoader *loader = PluginLoader::getInstance();
-
-        Plugin *plugin = loader->loadPlugin
-            (pluginKey, 48000, PluginLoader::ADAPT_ALL_SAFE);
-        if (!plugin) {
-            string pyerr("Failed to load plugin: "); pyerr += pluginKey;
-            PyErr_SetString(PyExc_TypeError,pyerr.c_str());
-            return 0;
-        }
-
-        outputs = plugin->getOutputDescriptors();
-
-        delete plugin;
-        
-    } else {
-
-        // we have a loaded plugin handle
-        
-        PyPluginObject *pd = getPluginObject(keyOrHandle);
-        if (!pd) return 0;
-
-        outputs = pd->plugin->getOutputDescriptors();
-    }
+    outputs = plugin->getOutputDescriptors();
 
     PyObject *pyList = PyList_New(outputs.size());
 
@@ -295,328 +218,9 @@
 	return 0;
     }
 
-    PyPluginObject *pd = PyPluginObject::create_internal();
-    pd->key = new string(pluginKey);
-    pd->plugin = plugin;
-    pd->inputSampleRate = inputSampleRate;
-    pd->isInitialised = false;
-    pd->channels = 0;
-    pd->blockSize = 0;
-    pd->stepSize = 0;
-    return (PyObject *)pd;
+    return PyPluginObject_From_Plugin(plugin);
 }
 
-static PyObject *
-vampyhost_initialise(PyObject *self, PyObject *args)
-{
-    cerr << "vampyhost_initialise" << endl;
-    
-    size_t channels, blockSize, stepSize;
-
-    if (!PyArg_ParseTuple (args, "nnn",
-			   (size_t) &channels,
-			   (size_t) &stepSize,
-			   (size_t) &blockSize)) {
-	PyErr_SetString(PyExc_TypeError,
-			"initialise() takes channel count, step size, and block size arguments");
-	return 0;
-    }
-
-    PyPluginObject *pd = getPluginObject(self);
-    if (!pd) return 0;
-
-    pd->channels = channels;
-    pd->stepSize = stepSize;
-    pd->blockSize = blockSize;
-
-    if (!pd->plugin->initialise(channels, stepSize, blockSize)) {
-        cerr << "Failed to initialise native plugin adapter with channels = " << channels << ", stepSize = " << stepSize << ", blockSize = " << blockSize << " and ADAPT_ALL_SAFE set" << endl;
-	PyErr_SetString(PyExc_TypeError,
-			"Plugin initialization failed");
-	return 0;
-    }
-
-    pd->isInitialised = true;
-
-    return Py_True;
-}
-
-static PyObject *
-vampyhost_reset(PyObject *self, PyObject *)
-{
-    cerr << "vampyhost_reset" << endl;
-    
-    PyPluginObject *pd = getPluginObject(self);
-    if (!pd) return 0;
-
-    if (!pd->isInitialised) {
-        PyErr_SetString(PyExc_StandardError,
-                        "Plugin has not been initialised");
-        return 0;
-    }
-        
-    pd->plugin->reset();
-    return Py_True;
-}
-
-static PyObject *
-vampyhost_getParameter(PyObject *self, PyObject *args)
-{
-    cerr << "vampyhost_getParameter" << endl;
-
-    PyObject *pyParam;
-
-    if (!PyArg_ParseTuple(args, "S", &pyParam)) {
-	PyErr_SetString(PyExc_TypeError,
-			"getParameter() takes parameter id (string) argument");
-	return 0; }
-
-    PyPluginObject *pd = getPluginObject(self);
-    if (!pd) return 0;
-
-    float value = pd->plugin->getParameter(PyString_AS_STRING(pyParam));
-    return PyFloat_FromDouble(double(value));
-}
-
-static PyObject *
-vampyhost_setParameter(PyObject *self, PyObject *args)
-{
-    cerr << "vampyhost_setParameter" << endl;
-
-    PyObject *pyParam;
-    float value;
-
-    if (!PyArg_ParseTuple(args, "Sf", &pyParam, &value)) {
-	PyErr_SetString(PyExc_TypeError,
-			"setParameter() takes parameter id (string), and value (float) arguments");
-	return 0; }
-
-    PyPluginObject *pd = getPluginObject(self);
-    if (!pd) return 0;
-
-    pd->plugin->setParameter(PyString_AS_STRING(pyParam), value);
-    return Py_True;
-}
-
-static PyObject *
-vampyhost_process(PyObject *self, PyObject *args)
-{
-    cerr << "vampyhost_process" << endl;
-
-    PyObject *pyBuffer;
-    PyObject *pyRealTime;
-
-    if (!PyArg_ParseTuple(args, "OO",
-			  &pyBuffer,			// Audio data
-			  &pyRealTime)) {		// TimeStamp
-	PyErr_SetString(PyExc_TypeError,
-			"process() takes plugin handle (object), buffer (2D array of channels * samples floats) and timestamp (RealTime) arguments");
-	return 0; }
-
-    if (!PyRealTime_Check(pyRealTime)) {
-	PyErr_SetString(PyExc_TypeError,"Valid timestamp required.");
-	return 0; }
-
-    if (!PyList_Check(pyBuffer)) {
-	PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input.");
-        return 0;
-    }
-
-    PyPluginObject *pd = getPluginObject(self);
-    if (!pd) return 0;
-
-    if (!pd->isInitialised) {
-	PyErr_SetString(PyExc_StandardError,
-			"Plugin has not been initialised.");
-	return 0;
-    }
-
-    int channels =  pd->channels;
-
-    if (PyList_GET_SIZE(pyBuffer) != channels) {
-        cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << endl;
-	PyErr_SetString(PyExc_TypeError, "Wrong number of channels");
-        return 0;
-    }
-
-    float **inbuf = new float *[channels];
-
-    VectorConversion typeConv;
-
-    cerr << "here!"  << endl;
-    
-    vector<vector<float> > data;
-    for (int c = 0; c < channels; ++c) {
-        PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c);
-        data.push_back(typeConv.PyValue_To_FloatVector(cbuf));
-    }
-    
-    for (int c = 0; c < channels; ++c) {
-        if (data[c].size() != pd->blockSize) {
-            cerr << "Wrong number of samples on channel " << c << ": expected " << pd->blockSize << " (plugin's block size), got " << data[c].size() << endl;
-            PyErr_SetString(PyExc_TypeError, "Wrong number of samples");
-            return 0;
-        }
-        inbuf[c] = &data[c][0];
-    }
-
-    cerr << "no, here!"  << endl;
-
-    RealTime timeStamp = *PyRealTime_AsRealTime(pyRealTime);
-
-    cerr << "no no, here!"  << endl;
-
-    Plugin::FeatureSet fs = pd->plugin->process(inbuf, timeStamp);
-
-    delete[] inbuf;
-
-    cerr << "no no no, here!"  << endl;
-    
-    VectorConversion conv;
-    
-    PyObject *pyFs = PyDict_New();
-
-    for (Plugin::FeatureSet::const_iterator fsi = fs.begin();
-         fsi != fs.end(); ++fsi) {
-
-        int fno = fsi->first;
-        const Plugin::FeatureList &fl = fsi->second;
-
-        if (!fl.empty()) {
-
-            PyObject *pyFl = PyList_New(fl.size());
-
-            for (int fli = 0; fli < (int)fl.size(); ++fli) {
-
-                const Plugin::Feature &f = fl[fli];
-                PyObject *pyF = PyDict_New();
-
-                if (f.hasTimestamp) {
-                    PyDict_SetItemString
-                        (pyF, "timestamp", PyRealTime_FromRealTime(f.timestamp));
-                }
-                if (f.hasDuration) {
-                    PyDict_SetItemString
-                        (pyF, "duration", PyRealTime_FromRealTime(f.duration));
-                }
-
-                PyDict_SetItemString
-                    (pyF, "label", PyString_FromString(f.label.c_str()));
-
-                if (!f.values.empty()) {
-                    PyDict_SetItemString
-                        (pyF, "values", conv.PyArray_From_FloatVector(f.values));
-                }
-
-                PyList_SET_ITEM(pyFl, fli, pyF);
-            }
-
-            PyObject *pyN = PyInt_FromLong(fno);
-            PyDict_SetItem(pyFs, pyN, pyFl);
-        }
-    }
-
-    cerr << "no you fool, here!"  << endl;
-    
-    return pyFs;
-}
-
-static PyObject *
-vampyhost_unload(PyObject *self, PyObject *)
-{
-    cerr << "vampyhost_unloadPlugin" << endl;
-    
-    PyPluginObject *pd = getPluginObject(self);
-    if (!pd) return 0;
-
-    delete pd->plugin;
-    pd->plugin = 0; // This is checked by getPluginObject, so we 
-                    // attempt to avoid repeated calls from blowing up
-
-    return Py_True;
-}
-
-static PyMethodDef PyPluginObject_methods[] =
-{
-    {"getParameter",	vampyhost_getParameter, METH_VARARGS,
-     xx_foo_doc}, //!!! fix all these!
-
-    {"setParameter",	vampyhost_setParameter, METH_VARARGS,
-     xx_foo_doc},
-
-    {"initialise",	vampyhost_initialise, METH_VARARGS,
-     xx_foo_doc},
-
-    {"reset",	vampyhost_reset, METH_NOARGS,
-     xx_foo_doc},
-
-    {"process",	vampyhost_process, METH_VARARGS,
-     xx_foo_doc},
-
-    {"unload", vampyhost_unload, METH_NOARGS,
-     xx_foo_doc},
-    
-    {0, 0}
-};
-
-static int
-PyPluginObject_setattr(PyPluginObject *self, char *name, PyObject *value)
-{
-    return -1;
-}
-
-static PyObject *
-PyPluginObject_getattr(PyPluginObject *self, char *name)
-{
-    return Py_FindMethod(PyPluginObject_methods, (PyObject *)self, name);
-}
-
-/* Doc:: 10.3 Type Objects */ /* static */ 
-PyTypeObject Plugin_Type = 
-{
-    PyObject_HEAD_INIT(NULL)
-    0,						/*ob_size*/
-    "vampyhost.Plugin",				/*tp_name*/
-    sizeof(PyPluginObject),	/*tp_basicsize*/
-    0,		/*tp_itemsize*/
-    (destructor)PyPluginObject_dealloc, /*tp_dealloc*/
-    0,						/*tp_print*/
-    (getattrfunc)PyPluginObject_getattr, /*tp_getattr*/
-    (setattrfunc)PyPluginObject_setattr, /*tp_setattr*/
-    0,						/*tp_compare*/
-    0,			/*tp_repr*/
-    0,	/*tp_as_number*/
-    0,						/*tp_as_sequence*/
-    0,						/*tp_as_mapping*/
-    0,						/*tp_hash*/
-    0,                      /*tp_call*/
-    0,                      /*tp_str*/
-    0,                      /*tp_getattro*/
-    0,                      /*tp_setattro*/
-    0,                      /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT,     /*tp_flags*/
-    "Plugin Object",      /*tp_doc*/
-    0,                      /*tp_traverse*/
-    0,                      /*tp_clear*/
-    0,                      /*tp_richcompare*/
-    0,                      /*tp_weaklistoffset*/
-    0,                      /*tp_iter*/
-    0,                      /*tp_iternext*/
-    PyPluginObject_methods,       /*tp_methods*/ 
-    0,                      /*tp_members*/
-    0,                      /*tp_getset*/
-    0,                      /*tp_base*/
-    0,                      /*tp_dict*/
-    0,                      /*tp_descr_get*/
-    0,                      /*tp_descr_set*/
-    0,                      /*tp_dictoffset*/
-    0,                      /*tp_init*/
-    PyType_GenericAlloc,         /*tp_alloc*/
-    0,           /*tp_new*/
-    PyObject_Del,			/*tp_free*/
-    0,                      /*tp_is_gc*/
-};
-
 // module methods table
 static PyMethodDef vampyhost_methods[] = {
 
@@ -641,12 +245,6 @@
     {0,		0}		/* sentinel */
 };
 
-PyPluginObject *
-PyPluginObject::create_internal()
-{
-    return (PyPluginObject *)PyType_GenericAlloc(&Plugin_Type, 0);
-}
-
 //Documentation for our new module
 PyDoc_STRVAR(module_doc, "This is a template module just for instruction.");