annotate vampyhost.cpp @ 23:9dc444c79aa5

Pull out the functions that act on a plugin from module to plugin object scope. Also reverse previous decision to remove unload(), I think it is needed
author Chris Cannam
date Tue, 25 Nov 2014 17:39:27 +0000
parents ccb5fef13104
children 392878bea53d
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 //include for python extension module: must be first
Chris@0 4 #include <Python.h>
Chris@14 5
Chris@14 6 // define a unique API pointer
Chris@14 7 #define PY_ARRAY_UNIQUE_SYMBOL VAMPY_ARRAY_API
Chris@14 8 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
Chris@14 9 #include "numpy/arrayobject.h"
Chris@14 10
Chris@0 11 #include <vampyhost.h>
Chris@12 12
Chris@12 13 #define HAVE_NUMPY 1 // Required
Chris@12 14
Chris@0 15 //includes for vamp host
Chris@1 16 #include "vamp-hostsdk/Plugin.h"
Chris@1 17 #include "vamp-hostsdk/PluginHostAdapter.h"
Chris@1 18 #include "vamp-hostsdk/PluginChannelAdapter.h"
Chris@1 19 #include "vamp-hostsdk/PluginInputDomainAdapter.h"
Chris@1 20 #include "vamp-hostsdk/PluginLoader.h"
Chris@16 21
Chris@16 22 #include "PyTypeConversions.h"
Chris@16 23 #include "PyRealTime.h"
Chris@0 24
Chris@0 25 #include <iostream>
Chris@0 26 #include <fstream>
Chris@0 27 #include <set>
Chris@0 28 #include <sndfile.h>
Chris@0 29
Chris@0 30 #include <cstring>
Chris@0 31 #include <cstdlib>
Chris@0 32 #include <string>
Chris@0 33
Chris@0 34 #include <cmath>
Chris@0 35
Chris@0 36 using namespace std;
Chris@0 37 using namespace Vamp;
Chris@0 38
Chris@0 39 using Vamp::Plugin;
Chris@0 40 using Vamp::PluginHostAdapter;
Chris@0 41 using Vamp::RealTime;
Chris@0 42 using Vamp::HostExt::PluginLoader;
Chris@0 43
Chris@0 44 #define HOST_VERSION "1.1"
Chris@0 45
Chris@16 46 // structure for holding plugin instance data
Chris@21 47 struct PyPluginObject
Chris@16 48 {
Chris@21 49 PyObject_HEAD
Chris@21 50 string *key;
Chris@16 51 Plugin *plugin;
Chris@16 52 float inputSampleRate;
Chris@16 53 bool isInitialised;
Chris@16 54 size_t channels;
Chris@16 55 size_t blockSize;
Chris@16 56 size_t stepSize;
Chris@21 57 static PyPluginObject *create_internal();
Chris@16 58 };
Chris@0 59
Chris@21 60 PyAPI_DATA(PyTypeObject) Plugin_Type;
Chris@21 61 #define PyPlugin_Check(v) PyObject_TypeCheck(v, &Plugin_Type)
Chris@21 62
Chris@21 63 static void
Chris@21 64 PyPluginObject_dealloc(PyPluginObject *self)
Chris@21 65 {
Chris@21 66 cerr << "PyPluginObject_dealloc" << endl;
Chris@21 67 delete self->key;
Chris@21 68 delete self->plugin;
Chris@21 69 PyObject_Del(self);
Chris@21 70 }
Chris@21 71
Chris@2 72 PyDoc_STRVAR(xx_foo_doc, "Some description"); //!!!
Chris@0 73
Chris@21 74 PyPluginObject *
Chris@21 75 getPluginObject(PyObject *pyPluginHandle)
Chris@21 76 {
Chris@21 77 cerr << "getPluginObject" << endl;
Chris@0 78
Chris@21 79 PyPluginObject *pd = 0;
Chris@21 80 if (PyPlugin_Check(pyPluginHandle)) {
Chris@21 81 pd = (PyPluginObject *)pyPluginHandle;
Chris@16 82 }
Chris@16 83 if (!pd || !pd->plugin) {
Chris@16 84 PyErr_SetString(PyExc_AttributeError,
Chris@16 85 "Invalid or already deleted plugin handle.");
Chris@16 86 return 0;
Chris@0 87 } else {
Chris@16 88 return pd;
Chris@0 89 }
Chris@0 90 }
Chris@0 91
Chris@0 92 static PyObject *
Chris@23 93 vampyhost_enumeratePlugins(PyObject *self, PyObject *)
Chris@0 94 {
Chris@21 95 cerr << "vampyhost_enumeratePlugins" << endl;
Chris@21 96
Chris@0 97 PluginLoader *loader = PluginLoader::getInstance();
Chris@0 98 vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
Chris@15 99 PyTypeConversions conv;
Chris@15 100 return conv.PyValue_From_StringVector(plugins);
Chris@0 101 }
Chris@0 102
Chris@15 103 static PyObject *
Chris@23 104 vampyhost_getPluginPath(PyObject *self, PyObject *)
Chris@15 105 {
Chris@21 106 cerr << "vampyhost_getPluginPath" << endl;
Chris@21 107
Chris@15 108 vector<string> path = PluginHostAdapter::getPluginPath();
Chris@15 109 PyTypeConversions conv;
Chris@15 110 return conv.PyValue_From_StringVector(path);
Chris@15 111 }
Chris@0 112
Chris@15 113 static string toPluginKey(PyObject *pyPluginKey)
Chris@0 114 {
Chris@21 115 cerr << "toPluginKey" << endl;
Chris@21 116
Chris@0 117 //convert to stl string
Chris@0 118 string pluginKey(PyString_AS_STRING(pyPluginKey));
Chris@0 119
Chris@0 120 //check pluginKey Validity
Chris@0 121 string::size_type ki = pluginKey.find(':');
Chris@0 122 if (ki == string::npos) {
Chris@0 123 PyErr_SetString(PyExc_TypeError,
Chris@15 124 "Plugin key must be of the form library:identifier");
Chris@15 125 return "";
Chris@0 126 }
Chris@0 127
Chris@15 128 return pluginKey;
Chris@15 129 }
Chris@15 130
Chris@15 131 static PyObject *
Chris@15 132 vampyhost_getLibraryFor(PyObject *self, PyObject *args)
Chris@15 133 {
Chris@21 134 cerr << "vampyhost_getLibraryFor" << endl;
Chris@21 135
Chris@15 136 PyObject *pyPluginKey;
Chris@15 137
Chris@15 138 if (!PyArg_ParseTuple(args, "S", &pyPluginKey)) {
Chris@15 139 PyErr_SetString(PyExc_TypeError,
Chris@15 140 "getLibraryPathForPlugin() takes plugin key (string) argument");
Chris@16 141 return 0; }
Chris@15 142
Chris@15 143 string pluginKey = toPluginKey(pyPluginKey);
Chris@16 144 if (pluginKey == "") return 0;
Chris@15 145
Chris@0 146 PluginLoader *loader = PluginLoader::getInstance();
Chris@0 147 string path = loader->getLibraryPathForPlugin(pluginKey);
Chris@0 148 PyObject *pyPath = PyString_FromString(path.c_str());
Chris@0 149 return pyPath;
Chris@0 150 }
Chris@0 151
Chris@0 152 static PyObject *
Chris@0 153 vampyhost_getPluginCategory(PyObject *self, PyObject *args)
Chris@0 154 {
Chris@21 155 cerr << "vampyhost_getPluginCategory" << endl;
Chris@21 156
Chris@0 157 PyObject *pyPluginKey;
Chris@0 158
Chris@0 159 if (!PyArg_ParseTuple(args, "S", &pyPluginKey)) {
Chris@0 160 PyErr_SetString(PyExc_TypeError,
Chris@15 161 "getPluginCategory() takes plugin key (string) argument");
Chris@16 162 return 0; }
Chris@0 163
Chris@15 164 string pluginKey = toPluginKey(pyPluginKey);
Chris@16 165 if (pluginKey == "") return 0;
Chris@0 166
Chris@0 167 PluginLoader *loader = PluginLoader::getInstance();
luis@7 168 PluginLoader::PluginCategoryHierarchy
Chris@0 169 category = loader->getPluginCategory(pluginKey);
Chris@0 170
Chris@15 171 PyTypeConversions conv;
Chris@15 172 return conv.PyValue_From_StringVector(category);
Chris@0 173 }
Chris@0 174
Chris@0 175 static PyObject *
Chris@0 176 vampyhost_getOutputList(PyObject *self, PyObject *args)
Chris@0 177 {
Chris@21 178 cerr << "vampyhost_getOutputList" << endl;
Chris@21 179
Chris@16 180 PyObject *keyOrHandle;
Chris@15 181 Plugin::OutputList outputs;
Chris@0 182
Chris@16 183 if (!PyArg_ParseTuple(args, "O", &keyOrHandle)) {
Chris@0 184 PyErr_SetString(PyExc_TypeError,
Chris@15 185 "getOutputList() takes plugin handle (object) or plugin key (string) argument");
Chris@16 186 return 0;
Chris@0 187 }
Chris@0 188
Chris@16 189 if (PyString_Check(keyOrHandle) ) {
Chris@0 190
Chris@15 191 // we have a plugin key
Chris@0 192
Chris@16 193 string pluginKey = toPluginKey(keyOrHandle);
Chris@16 194 if (pluginKey == "") return 0;
Chris@15 195
Chris@15 196 PluginLoader *loader = PluginLoader::getInstance();
Chris@15 197
Chris@15 198 Plugin *plugin = loader->loadPlugin
Chris@15 199 (pluginKey, 48000, PluginLoader::ADAPT_ALL_SAFE);
Chris@15 200 if (!plugin) {
Chris@15 201 string pyerr("Failed to load plugin: "); pyerr += pluginKey;
Chris@15 202 PyErr_SetString(PyExc_TypeError,pyerr.c_str());
Chris@16 203 return 0;
Chris@15 204 }
Chris@15 205
Chris@15 206 outputs = plugin->getOutputDescriptors();
Chris@15 207
Chris@15 208 delete plugin;
Chris@15 209
Chris@0 210 } else {
luis@7 211
Chris@15 212 // we have a loaded plugin handle
Chris@15 213
Chris@21 214 PyPluginObject *pd = getPluginObject(keyOrHandle);
Chris@16 215 if (!pd) return 0;
Chris@0 216
Chris@16 217 outputs = pd->plugin->getOutputDescriptors();
luis@7 218 }
luis@7 219
Chris@0 220 PyObject *pyList = PyList_New(outputs.size());
Chris@0 221
Chris@0 222 for (size_t i = 0; i < outputs.size(); ++i) {
luis@7 223 PyObject *pyOutputId =
Chris@0 224 PyString_FromString(outputs[i].identifier.c_str());
Chris@15 225 PyList_SET_ITEM(pyList, i, pyOutputId);
Chris@0 226 }
Chris@0 227
Chris@0 228 return pyList;
Chris@0 229 }
Chris@0 230
Chris@0 231 static PyObject *
Chris@0 232 vampyhost_loadPlugin(PyObject *self, PyObject *args)
Chris@0 233 {
Chris@21 234 cerr << "vampyhost_loadPlugin" << endl;
Chris@21 235
Chris@0 236 PyObject *pyPluginKey;
Chris@0 237 float inputSampleRate;
Chris@0 238
luis@7 239 if (!PyArg_ParseTuple(args, "Sf",
Chris@0 240 &pyPluginKey,
Chris@0 241 &inputSampleRate)) {
Chris@0 242 PyErr_SetString(PyExc_TypeError,
Chris@20 243 "loadPlugin() takes plugin key (string) and sample rate (float) arguments");
Chris@16 244 return 0; }
Chris@0 245
Chris@15 246 string pluginKey = toPluginKey(pyPluginKey);
Chris@16 247 if (pluginKey == "") return 0;
Chris@0 248
Chris@0 249 PluginLoader *loader = PluginLoader::getInstance();
luis@7 250
Chris@15 251 Plugin *plugin = loader->loadPlugin(pluginKey, inputSampleRate,
Chris@15 252 PluginLoader::ADAPT_ALL_SAFE);
luis@7 253 if (!plugin) {
Chris@0 254 string pyerr("Failed to load plugin: "); pyerr += pluginKey;
luis@7 255 PyErr_SetString(PyExc_TypeError,pyerr.c_str());
Chris@16 256 return 0;
luis@7 257 }
Chris@15 258
Chris@21 259 PyPluginObject *pd = PyPluginObject::create_internal();
Chris@21 260 pd->key = new string(pluginKey);
Chris@21 261 pd->plugin = plugin;
Chris@21 262 pd->inputSampleRate = inputSampleRate;
Chris@21 263 pd->isInitialised = false;
Chris@21 264 pd->channels = 0;
Chris@21 265 pd->blockSize = 0;
Chris@21 266 pd->stepSize = 0;
Chris@21 267 return (PyObject *)pd;
Chris@0 268 }
Chris@0 269
Chris@0 270 static PyObject *
Chris@0 271 vampyhost_initialise(PyObject *self, PyObject *args)
Chris@0 272 {
Chris@21 273 cerr << "vampyhost_initialise" << endl;
Chris@21 274
luis@7 275 size_t channels, blockSize, stepSize;
Chris@0 276
Chris@23 277 if (!PyArg_ParseTuple (args, "nnn",
luis@7 278 (size_t) &channels,
luis@7 279 (size_t) &stepSize,
Chris@23 280 (size_t) &blockSize)) {
Chris@0 281 PyErr_SetString(PyExc_TypeError,
Chris@23 282 "initialise() takes channel count, step size, and block size arguments");
Chris@16 283 return 0;
Chris@0 284 }
Chris@0 285
Chris@23 286 PyPluginObject *pd = getPluginObject(self);
Chris@16 287 if (!pd) return 0;
Chris@0 288
Chris@16 289 pd->channels = channels;
Chris@16 290 pd->stepSize = stepSize;
Chris@16 291 pd->blockSize = blockSize;
Chris@0 292
Chris@16 293 if (!pd->plugin->initialise(channels, stepSize, blockSize)) {
Chris@17 294 cerr << "Failed to initialise native plugin adapter with channels = " << channels << ", stepSize = " << stepSize << ", blockSize = " << blockSize << " and ADAPT_ALL_SAFE set" << endl;
Chris@0 295 PyErr_SetString(PyExc_TypeError,
Chris@17 296 "Plugin initialization failed");
Chris@16 297 return 0;
Chris@6 298 }
Chris@0 299
Chris@16 300 pd->isInitialised = true;
luis@7 301
Chris@0 302 return Py_True;
Chris@0 303 }
Chris@0 304
Chris@0 305 static PyObject *
Chris@23 306 vampyhost_reset(PyObject *self, PyObject *)
Chris@18 307 {
Chris@21 308 cerr << "vampyhost_reset" << endl;
Chris@21 309
Chris@23 310 PyPluginObject *pd = getPluginObject(self);
Chris@18 311 if (!pd) return 0;
Chris@18 312
Chris@18 313 if (!pd->isInitialised) {
Chris@18 314 PyErr_SetString(PyExc_StandardError,
Chris@18 315 "Plugin has not been initialised");
Chris@18 316 return 0;
Chris@18 317 }
Chris@18 318
Chris@18 319 pd->plugin->reset();
Chris@18 320 return Py_True;
Chris@18 321 }
Chris@18 322
Chris@18 323 static PyObject *
Chris@20 324 vampyhost_getParameter(PyObject *self, PyObject *args)
Chris@20 325 {
Chris@21 326 cerr << "vampyhost_getParameter" << endl;
Chris@21 327
Chris@20 328 PyObject *pyParam;
Chris@20 329
Chris@23 330 if (!PyArg_ParseTuple(args, "S", &pyParam)) {
Chris@20 331 PyErr_SetString(PyExc_TypeError,
Chris@23 332 "getParameter() takes parameter id (string) argument");
Chris@20 333 return 0; }
Chris@20 334
Chris@23 335 PyPluginObject *pd = getPluginObject(self);
Chris@20 336 if (!pd) return 0;
Chris@20 337
Chris@20 338 float value = pd->plugin->getParameter(PyString_AS_STRING(pyParam));
Chris@20 339 return PyFloat_FromDouble(double(value));
Chris@20 340 }
Chris@20 341
Chris@20 342 static PyObject *
Chris@20 343 vampyhost_setParameter(PyObject *self, PyObject *args)
Chris@20 344 {
Chris@21 345 cerr << "vampyhost_setParameter" << endl;
Chris@21 346
Chris@20 347 PyObject *pyParam;
Chris@20 348 float value;
Chris@20 349
Chris@23 350 if (!PyArg_ParseTuple(args, "Sf", &pyParam, &value)) {
Chris@20 351 PyErr_SetString(PyExc_TypeError,
Chris@23 352 "setParameter() takes parameter id (string), and value (float) arguments");
Chris@20 353 return 0; }
Chris@20 354
Chris@23 355 PyPluginObject *pd = getPluginObject(self);
Chris@20 356 if (!pd) return 0;
Chris@20 357
Chris@20 358 pd->plugin->setParameter(PyString_AS_STRING(pyParam), value);
Chris@20 359 return Py_True;
Chris@20 360 }
Chris@20 361
Chris@20 362 static PyObject *
Chris@0 363 vampyhost_process(PyObject *self, PyObject *args)
Chris@0 364 {
Chris@21 365 cerr << "vampyhost_process" << endl;
Chris@21 366
Chris@0 367 PyObject *pyBuffer;
Chris@0 368 PyObject *pyRealTime;
Chris@0 369
Chris@23 370 if (!PyArg_ParseTuple(args, "OO",
Chris@0 371 &pyBuffer, // Audio data
Chris@0 372 &pyRealTime)) { // TimeStamp
Chris@0 373 PyErr_SetString(PyExc_TypeError,
Chris@17 374 "process() takes plugin handle (object), buffer (2D array of channels * samples floats) and timestamp (RealTime) arguments");
Chris@16 375 return 0; }
Chris@0 376
Chris@0 377 if (!PyRealTime_Check(pyRealTime)) {
Chris@0 378 PyErr_SetString(PyExc_TypeError,"Valid timestamp required.");
Chris@16 379 return 0; }
Chris@0 380
Chris@17 381 if (!PyList_Check(pyBuffer)) {
Chris@17 382 PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input.");
Chris@17 383 return 0;
Chris@17 384 }
Chris@17 385
Chris@23 386 PyPluginObject *pd = getPluginObject(self);
Chris@16 387 if (!pd) return 0;
Chris@0 388
Chris@0 389 if (!pd->isInitialised) {
Chris@0 390 PyErr_SetString(PyExc_StandardError,
Chris@0 391 "Plugin has not been initialised.");
Chris@16 392 return 0;
Chris@16 393 }
Chris@0 394
Chris@12 395 int channels = pd->channels;
Chris@0 396
Chris@4 397 if (PyList_GET_SIZE(pyBuffer) != channels) {
Chris@17 398 cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << endl;
Chris@4 399 PyErr_SetString(PyExc_TypeError, "Wrong number of channels");
Chris@16 400 return 0;
Chris@4 401 }
Chris@0 402
Chris@4 403 float **inbuf = new float *[channels];
Chris@0 404
Chris@12 405 PyTypeConversions typeConv;
Chris@12 406 typeConv.setNumpyInstalled(true);
Chris@17 407
Chris@17 408 cerr << "here!" << endl;
Chris@12 409
Chris@12 410 vector<vector<float> > data;
Chris@4 411 for (int c = 0; c < channels; ++c) {
Chris@4 412 PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c);
Chris@17 413 data.push_back(typeConv.PyValue_To_FloatVector(cbuf));
Chris@12 414 }
Chris@12 415
Chris@12 416 for (int c = 0; c < channels; ++c) {
Chris@17 417 if (data[c].size() != pd->blockSize) {
Chris@17 418 cerr << "Wrong number of samples on channel " << c << ": expected " << pd->blockSize << " (plugin's block size), got " << data[c].size() << endl;
Chris@17 419 PyErr_SetString(PyExc_TypeError, "Wrong number of samples");
Chris@17 420 return 0;
Chris@17 421 }
Chris@12 422 inbuf[c] = &data[c][0];
Chris@4 423 }
Chris@0 424
Chris@17 425 cerr << "no, here!" << endl;
Chris@17 426
Chris@12 427 RealTime timeStamp = *PyRealTime_AsRealTime(pyRealTime);
Chris@0 428
Chris@18 429 cerr << "no no, here!" << endl;
Chris@0 430
Chris@18 431 Plugin::FeatureSet fs = pd->plugin->process(inbuf, timeStamp);
Chris@0 432
Chris@4 433 delete[] inbuf;
Chris@0 434
Chris@18 435 cerr << "no no no, here!" << endl;
Chris@18 436
Chris@18 437 PyTypeConversions conv;
Chris@18 438 conv.setNumpyInstalled(true);
Chris@18 439
Chris@18 440 PyObject *pyFs = PyDict_New();
Chris@0 441
Chris@18 442 for (Plugin::FeatureSet::const_iterator fsi = fs.begin();
Chris@18 443 fsi != fs.end(); ++fsi) {
Chris@18 444
Chris@18 445 int fno = fsi->first;
Chris@18 446 const Plugin::FeatureList &fl = fsi->second;
Chris@18 447
Chris@18 448 if (!fl.empty()) {
Chris@18 449
Chris@18 450 PyObject *pyFl = PyList_New(fl.size());
Chris@18 451
Chris@18 452 for (int fli = 0; fli < (int)fl.size(); ++fli) {
Chris@18 453
Chris@18 454 const Plugin::Feature &f = fl[fli];
Chris@18 455 PyObject *pyF = PyDict_New();
Chris@18 456
Chris@18 457 if (f.hasTimestamp) {
Chris@18 458 PyDict_SetItemString
Chris@18 459 (pyF, "timestamp", PyRealTime_FromRealTime(f.timestamp));
Chris@18 460 }
Chris@18 461 if (f.hasDuration) {
Chris@18 462 PyDict_SetItemString
Chris@18 463 (pyF, "duration", PyRealTime_FromRealTime(f.duration));
Chris@18 464 }
Chris@18 465
Chris@18 466 PyDict_SetItemString
Chris@18 467 (pyF, "label", PyString_FromString(f.label.c_str()));
Chris@18 468
Chris@18 469 if (!f.values.empty()) {
Chris@18 470 PyDict_SetItemString
Chris@18 471 (pyF, "values", conv.FloatVector_To_PyArray(f.values));
Chris@18 472 }
Chris@18 473
Chris@18 474 PyList_SET_ITEM(pyFl, fli, pyF);
Chris@18 475 }
Chris@18 476
Chris@18 477 PyObject *pyN = PyInt_FromLong(fno);
Chris@18 478 PyDict_SetItem(pyFs, pyN, pyFl);
Chris@18 479 }
Chris@18 480 }
Chris@18 481
Chris@18 482 cerr << "no you fool, here!" << endl;
Chris@18 483
Chris@18 484 return pyFs;
Chris@0 485 }
Chris@0 486
Chris@23 487 static PyObject *
Chris@23 488 vampyhost_unload(PyObject *self, PyObject *)
Chris@23 489 {
Chris@23 490 cerr << "vampyhost_unloadPlugin" << endl;
Chris@23 491
Chris@23 492 PyPluginObject *pd = getPluginObject(self);
Chris@23 493 if (!pd) return 0;
Chris@23 494
Chris@23 495 delete pd->plugin;
Chris@23 496 pd->plugin = 0; // This is checked by getPluginObject, so we
Chris@23 497 // attempt to avoid repeated calls from blowing up
Chris@23 498
Chris@23 499 return Py_True;
Chris@23 500 }
Chris@23 501
Chris@21 502 static PyMethodDef PyPluginObject_methods[] =
Chris@21 503 {
Chris@23 504 {"getParameter", vampyhost_getParameter, METH_VARARGS,
Chris@23 505 xx_foo_doc}, //!!! fix all these!
Chris@23 506
Chris@23 507 {"setParameter", vampyhost_setParameter, METH_VARARGS,
Chris@23 508 xx_foo_doc},
Chris@23 509
Chris@23 510 {"initialise", vampyhost_initialise, METH_VARARGS,
Chris@23 511 xx_foo_doc},
Chris@23 512
Chris@23 513 {"reset", vampyhost_reset, METH_NOARGS,
Chris@23 514 xx_foo_doc},
Chris@23 515
Chris@23 516 {"process", vampyhost_process, METH_VARARGS,
Chris@23 517 xx_foo_doc},
Chris@23 518
Chris@23 519 {"unload", vampyhost_unload, METH_NOARGS,
Chris@23 520 xx_foo_doc},
Chris@23 521
Chris@21 522 {0, 0}
Chris@21 523 };
Chris@21 524
Chris@23 525 static int
Chris@23 526 PyPluginObject_setattr(PyPluginObject *self, char *name, PyObject *value)
Chris@23 527 {
Chris@23 528 return -1;
Chris@23 529 }
Chris@23 530
Chris@23 531 static PyObject *
Chris@23 532 PyPluginObject_getattr(PyPluginObject *self, char *name)
Chris@23 533 {
Chris@23 534 return Py_FindMethod(PyPluginObject_methods, (PyObject *)self, name);
Chris@23 535 }
Chris@23 536
Chris@21 537 /* Doc:: 10.3 Type Objects */ /* static */
Chris@21 538 PyTypeObject Plugin_Type =
Chris@21 539 {
Chris@21 540 PyObject_HEAD_INIT(NULL)
Chris@21 541 0, /*ob_size*/
Chris@21 542 "vampyhost.Plugin", /*tp_name*/
Chris@21 543 sizeof(PyPluginObject), /*tp_basicsize*/
Chris@21 544 0, /*tp_itemsize*/
Chris@21 545 (destructor)PyPluginObject_dealloc, /*tp_dealloc*/
Chris@21 546 0, /*tp_print*/
Chris@23 547 (getattrfunc)PyPluginObject_getattr, /*tp_getattr*/
Chris@23 548 (setattrfunc)PyPluginObject_setattr, /*tp_setattr*/
Chris@21 549 0, /*tp_compare*/
Chris@21 550 0, /*tp_repr*/
Chris@21 551 0, /*tp_as_number*/
Chris@21 552 0, /*tp_as_sequence*/
Chris@21 553 0, /*tp_as_mapping*/
Chris@21 554 0, /*tp_hash*/
Chris@21 555 0, /*tp_call*/
Chris@21 556 0, /*tp_str*/
Chris@21 557 0, /*tp_getattro*/
Chris@21 558 0, /*tp_setattro*/
Chris@21 559 0, /*tp_as_buffer*/
Chris@21 560 Py_TPFLAGS_DEFAULT, /*tp_flags*/
Chris@21 561 "Plugin Object", /*tp_doc*/
Chris@21 562 0, /*tp_traverse*/
Chris@21 563 0, /*tp_clear*/
Chris@21 564 0, /*tp_richcompare*/
Chris@21 565 0, /*tp_weaklistoffset*/
Chris@21 566 0, /*tp_iter*/
Chris@21 567 0, /*tp_iternext*/
Chris@21 568 PyPluginObject_methods, /*tp_methods*/
Chris@21 569 0, /*tp_members*/
Chris@21 570 0, /*tp_getset*/
Chris@21 571 0, /*tp_base*/
Chris@21 572 0, /*tp_dict*/
Chris@21 573 0, /*tp_descr_get*/
Chris@21 574 0, /*tp_descr_set*/
Chris@21 575 0, /*tp_dictoffset*/
Chris@21 576 0, /*tp_init*/
Chris@21 577 PyType_GenericAlloc, /*tp_alloc*/
Chris@21 578 0, /*tp_new*/
Chris@21 579 PyObject_Del, /*tp_free*/
Chris@21 580 0, /*tp_is_gc*/
Chris@21 581 };
Chris@0 582
Chris@18 583 // module methods table
Chris@0 584 static PyMethodDef vampyhost_methods[] = {
Chris@0 585
Chris@18 586 {"listPlugins", vampyhost_enumeratePlugins, METH_NOARGS,
Chris@0 587 xx_foo_doc},
Chris@0 588
Chris@15 589 {"getPluginPath", vampyhost_getPluginPath, METH_NOARGS,
Chris@15 590 xx_foo_doc},
Chris@15 591
Chris@18 592 {"getCategoryOf", vampyhost_getPluginCategory, METH_VARARGS,
Chris@0 593 xx_foo_doc},
Chris@0 594
Chris@18 595 {"getLibraryFor", vampyhost_getLibraryFor, METH_VARARGS,
Chris@0 596 xx_foo_doc},
Chris@0 597
Chris@18 598 {"getOutputsOf", vampyhost_getOutputList, METH_VARARGS,
Chris@0 599 xx_foo_doc},
Chris@0 600
Chris@0 601 {"loadPlugin", vampyhost_loadPlugin, METH_VARARGS,
Chris@0 602 xx_foo_doc},
Chris@0 603
Chris@16 604 {0, 0} /* sentinel */
Chris@0 605 };
Chris@0 606
Chris@21 607 PyPluginObject *
Chris@21 608 PyPluginObject::create_internal()
Chris@21 609 {
Chris@21 610 return (PyPluginObject *)PyType_GenericAlloc(&Plugin_Type, 0);
Chris@21 611 }
Chris@21 612
Chris@0 613 //Documentation for our new module
Chris@0 614 PyDoc_STRVAR(module_doc, "This is a template module just for instruction.");
Chris@0 615
Chris@14 616
Chris@14 617
Chris@0 618 /* Initialization function for the module (*must* be called initxx) */
Chris@0 619
Chris@0 620 //module initialization (includes extern C {...} as necessary)
Chris@0 621 PyMODINIT_FUNC
Chris@0 622 initvampyhost(void)
Chris@0 623 {
Chris@0 624 PyObject *m;
Chris@0 625
Chris@0 626 /* Finalize the type object including setting type of the new type
luis@7 627 * object; doing it here is required for portability to Windows
Chris@0 628 * without requiring C++. */
Chris@0 629
Chris@0 630 if (PyType_Ready(&RealTime_Type) < 0)
Chris@0 631 return;
Chris@0 632
Chris@0 633 /* Create the module and add the functions */
Chris@0 634 m = Py_InitModule3("vampyhost", vampyhost_methods, module_doc);
Chris@16 635 if (!m) return;
Chris@0 636
Chris@14 637 import_array();
Chris@14 638
Chris@17 639 PyModule_AddObject(m, "RealTime", (PyObject *)&RealTime_Type);
Chris@0 640 }