annotate vampyhost.cpp @ 20:8e5cefa70c99

Parameter settings
author Chris Cannam
date Tue, 25 Nov 2014 12:48:05 +0000
parents 4b9adb4b532f
children 4b4a7ec1080d
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@16 47 struct PyPluginData
Chris@16 48 {
Chris@16 49 PyPluginData(string k, Plugin *p, float rate) :
Chris@16 50 key(k),
Chris@16 51 plugin(p),
Chris@16 52 inputSampleRate(rate),
Chris@16 53 isInitialised(false),
Chris@16 54 channels(0),
Chris@16 55 blockSize(0),
Chris@16 56 stepSize(0) {
Chris@16 57 }
Chris@16 58
Chris@16 59 string key;
Chris@16 60 Plugin *plugin;
Chris@16 61 float inputSampleRate;
Chris@16 62 bool isInitialised;
Chris@16 63 size_t channels;
Chris@16 64 size_t blockSize;
Chris@16 65 size_t stepSize;
Chris@16 66 };
Chris@0 67
Chris@0 68 /* MODULE HELPER FUNCTIONS */
Chris@2 69 PyDoc_STRVAR(xx_foo_doc, "Some description"); //!!!
Chris@0 70
Chris@16 71 //!!! nb "The CObject API is deprecated" https://docs.python.org/2/c-api/cobject.html
Chris@0 72
Chris@16 73 PyPluginData *
Chris@16 74 getPluginData(PyObject *pyPluginHandle)
Chris@16 75 {
Chris@16 76 PyPluginData *pd = 0;
Chris@16 77 if (PyCObject_Check(pyPluginHandle)) {
Chris@16 78 pd = (PyPluginData *)PyCObject_AsVoidPtr(pyPluginHandle);
Chris@16 79 }
Chris@16 80 if (!pd || !pd->plugin) {
Chris@16 81 PyErr_SetString(PyExc_AttributeError,
Chris@16 82 "Invalid or already deleted plugin handle.");
Chris@16 83 return 0;
Chris@0 84 } else {
Chris@16 85 return pd;
Chris@0 86 }
Chris@0 87 }
Chris@0 88
Chris@0 89 static PyObject *
Chris@0 90 vampyhost_enumeratePlugins(PyObject *self, PyObject *args)
Chris@0 91 {
Chris@0 92 PluginLoader *loader = PluginLoader::getInstance();
Chris@0 93 vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
Chris@15 94 PyTypeConversions conv;
Chris@15 95 return conv.PyValue_From_StringVector(plugins);
Chris@0 96 }
Chris@0 97
Chris@15 98 static PyObject *
Chris@15 99 vampyhost_getPluginPath(PyObject *self, PyObject *args)
Chris@15 100 {
Chris@15 101 vector<string> path = PluginHostAdapter::getPluginPath();
Chris@15 102 PyTypeConversions conv;
Chris@15 103 return conv.PyValue_From_StringVector(path);
Chris@15 104 }
Chris@0 105
Chris@15 106 static string toPluginKey(PyObject *pyPluginKey)
Chris@0 107 {
Chris@0 108 //convert to stl string
Chris@0 109 string pluginKey(PyString_AS_STRING(pyPluginKey));
Chris@0 110
Chris@0 111 //check pluginKey Validity
Chris@0 112 string::size_type ki = pluginKey.find(':');
Chris@0 113 if (ki == string::npos) {
Chris@0 114 PyErr_SetString(PyExc_TypeError,
Chris@15 115 "Plugin key must be of the form library:identifier");
Chris@15 116 return "";
Chris@0 117 }
Chris@0 118
Chris@15 119 return pluginKey;
Chris@15 120 }
Chris@15 121
Chris@15 122 static PyObject *
Chris@15 123 vampyhost_getLibraryFor(PyObject *self, PyObject *args)
Chris@15 124 {
Chris@15 125 PyObject *pyPluginKey;
Chris@15 126
Chris@15 127 if (!PyArg_ParseTuple(args, "S", &pyPluginKey)) {
Chris@15 128 PyErr_SetString(PyExc_TypeError,
Chris@15 129 "getLibraryPathForPlugin() takes plugin key (string) argument");
Chris@16 130 return 0; }
Chris@15 131
Chris@15 132 string pluginKey = toPluginKey(pyPluginKey);
Chris@16 133 if (pluginKey == "") return 0;
Chris@15 134
Chris@0 135 PluginLoader *loader = PluginLoader::getInstance();
Chris@0 136 string path = loader->getLibraryPathForPlugin(pluginKey);
Chris@0 137 PyObject *pyPath = PyString_FromString(path.c_str());
Chris@0 138 return pyPath;
Chris@0 139 }
Chris@0 140
Chris@0 141 static PyObject *
Chris@0 142 vampyhost_getPluginCategory(PyObject *self, PyObject *args)
Chris@0 143 {
Chris@0 144 PyObject *pyPluginKey;
Chris@0 145
Chris@0 146 if (!PyArg_ParseTuple(args, "S", &pyPluginKey)) {
Chris@0 147 PyErr_SetString(PyExc_TypeError,
Chris@15 148 "getPluginCategory() takes plugin key (string) argument");
Chris@16 149 return 0; }
Chris@0 150
Chris@15 151 string pluginKey = toPluginKey(pyPluginKey);
Chris@16 152 if (pluginKey == "") return 0;
Chris@0 153
Chris@0 154 PluginLoader *loader = PluginLoader::getInstance();
luis@7 155 PluginLoader::PluginCategoryHierarchy
Chris@0 156 category = loader->getPluginCategory(pluginKey);
Chris@0 157
Chris@15 158 PyTypeConversions conv;
Chris@15 159 return conv.PyValue_From_StringVector(category);
Chris@0 160 }
Chris@0 161
Chris@0 162 static PyObject *
Chris@0 163 vampyhost_getOutputList(PyObject *self, PyObject *args)
Chris@0 164 {
Chris@16 165 PyObject *keyOrHandle;
Chris@15 166 Plugin::OutputList outputs;
Chris@0 167
Chris@16 168 if (!PyArg_ParseTuple(args, "O", &keyOrHandle)) {
Chris@0 169 PyErr_SetString(PyExc_TypeError,
Chris@15 170 "getOutputList() takes plugin handle (object) or plugin key (string) argument");
Chris@16 171 return 0;
Chris@0 172 }
Chris@0 173
Chris@16 174 if (PyString_Check(keyOrHandle) ) {
Chris@0 175
Chris@15 176 // we have a plugin key
Chris@0 177
Chris@16 178 string pluginKey = toPluginKey(keyOrHandle);
Chris@16 179 if (pluginKey == "") return 0;
Chris@15 180
Chris@15 181 PluginLoader *loader = PluginLoader::getInstance();
Chris@15 182
Chris@15 183 Plugin *plugin = loader->loadPlugin
Chris@15 184 (pluginKey, 48000, PluginLoader::ADAPT_ALL_SAFE);
Chris@15 185 if (!plugin) {
Chris@15 186 string pyerr("Failed to load plugin: "); pyerr += pluginKey;
Chris@15 187 PyErr_SetString(PyExc_TypeError,pyerr.c_str());
Chris@16 188 return 0;
Chris@15 189 }
Chris@15 190
Chris@15 191 outputs = plugin->getOutputDescriptors();
Chris@15 192
Chris@15 193 delete plugin;
Chris@15 194
Chris@0 195 } else {
luis@7 196
Chris@15 197 // we have a loaded plugin handle
Chris@15 198
Chris@16 199 PyPluginData *pd = getPluginData(keyOrHandle);
Chris@16 200 if (!pd) return 0;
Chris@0 201
Chris@16 202 outputs = pd->plugin->getOutputDescriptors();
luis@7 203 }
luis@7 204
Chris@0 205 PyObject *pyList = PyList_New(outputs.size());
Chris@0 206
Chris@0 207 for (size_t i = 0; i < outputs.size(); ++i) {
luis@7 208 PyObject *pyOutputId =
Chris@0 209 PyString_FromString(outputs[i].identifier.c_str());
Chris@15 210 PyList_SET_ITEM(pyList, i, pyOutputId);
Chris@0 211 }
Chris@0 212
Chris@0 213 return pyList;
Chris@0 214 }
Chris@0 215
Chris@0 216 static PyObject *
Chris@0 217 vampyhost_loadPlugin(PyObject *self, PyObject *args)
Chris@0 218 {
Chris@0 219 PyObject *pyPluginKey;
Chris@0 220 float inputSampleRate;
Chris@0 221
luis@7 222 if (!PyArg_ParseTuple(args, "Sf",
Chris@0 223 &pyPluginKey,
Chris@0 224 &inputSampleRate)) {
Chris@0 225 PyErr_SetString(PyExc_TypeError,
Chris@20 226 "loadPlugin() takes plugin key (string) and sample rate (float) arguments");
Chris@16 227 return 0; }
Chris@0 228
Chris@15 229 string pluginKey = toPluginKey(pyPluginKey);
Chris@16 230 if (pluginKey == "") return 0;
Chris@0 231
Chris@0 232 PluginLoader *loader = PluginLoader::getInstance();
luis@7 233
Chris@15 234 Plugin *plugin = loader->loadPlugin(pluginKey, inputSampleRate,
Chris@15 235 PluginLoader::ADAPT_ALL_SAFE);
luis@7 236 if (!plugin) {
Chris@0 237 string pyerr("Failed to load plugin: "); pyerr += pluginKey;
luis@7 238 PyErr_SetString(PyExc_TypeError,pyerr.c_str());
Chris@16 239 return 0;
luis@7 240 }
Chris@15 241
Chris@16 242 PyPluginData *pd = new PyPluginData(pluginKey, plugin, inputSampleRate);
Chris@16 243 return PyCObject_FromVoidPtr(pd, 0);
Chris@0 244 }
Chris@0 245
Chris@0 246 static PyObject *
Chris@0 247 vampyhost_unloadPlugin(PyObject *self, PyObject *args)
Chris@0 248 {
Chris@0 249 PyObject *pyPluginHandle;
Chris@0 250
Chris@0 251 if (!PyArg_ParseTuple(args, "O", &pyPluginHandle)) {
Chris@0 252 PyErr_SetString(PyExc_TypeError,
Chris@16 253 "unloadPlugin() takes plugin handle (object) argument");
Chris@16 254 return 0;
Chris@16 255 }
Chris@0 256
Chris@16 257 PyPluginData *pd = getPluginData(pyPluginHandle);
Chris@16 258 if (!pd) return 0;
Chris@0 259
Chris@16 260 /* Prevent repeated calls from causing segfault since it will fail
Chris@16 261 * type checking the 2nd time: */
Chris@16 262 PyCObject_SetVoidPtr(pyPluginHandle, 0);
Chris@0 263
Chris@16 264 delete pd->plugin;
Chris@0 265 delete pd;
Chris@0 266 return pyPluginHandle;
Chris@0 267 }
Chris@0 268
Chris@0 269 static PyObject *
Chris@0 270 vampyhost_initialise(PyObject *self, PyObject *args)
Chris@0 271 {
Chris@0 272 PyObject *pyPluginHandle;
luis@7 273 size_t channels, blockSize, stepSize;
Chris@0 274
luis@7 275 if (!PyArg_ParseTuple (args, "Onnn", &pyPluginHandle,
luis@7 276 (size_t) &channels,
luis@7 277 (size_t) &stepSize,
luis@7 278 (size_t) &blockSize))
Chris@0 279 {
Chris@0 280 PyErr_SetString(PyExc_TypeError,
Chris@17 281 "initialise() takes plugin handle (object), channel count, step size, and block size arguments");
Chris@16 282 return 0;
Chris@0 283 }
Chris@0 284
Chris@16 285 PyPluginData *pd = getPluginData(pyPluginHandle);
Chris@16 286 if (!pd) return 0;
Chris@0 287
Chris@16 288 pd->channels = channels;
Chris@16 289 pd->stepSize = stepSize;
Chris@16 290 pd->blockSize = blockSize;
Chris@0 291
Chris@16 292 if (!pd->plugin->initialise(channels, stepSize, blockSize)) {
Chris@17 293 cerr << "Failed to initialise native plugin adapter with channels = " << channels << ", stepSize = " << stepSize << ", blockSize = " << blockSize << " and ADAPT_ALL_SAFE set" << endl;
Chris@0 294 PyErr_SetString(PyExc_TypeError,
Chris@17 295 "Plugin initialization failed");
Chris@16 296 return 0;
Chris@6 297 }
Chris@0 298
Chris@16 299 pd->isInitialised = true;
luis@7 300
Chris@0 301 return Py_True;
Chris@0 302 }
Chris@0 303
Chris@0 304 static PyObject *
Chris@18 305 vampyhost_reset(PyObject *self, PyObject *args)
Chris@18 306 {
Chris@18 307 PyObject *pyPluginHandle;
Chris@18 308
Chris@18 309 if (!PyArg_ParseTuple (args, "O", &pyPluginHandle))
Chris@18 310 {
Chris@18 311 PyErr_SetString(PyExc_TypeError,
Chris@18 312 "initialise() takes plugin handle (object) argument");
Chris@18 313 return 0;
Chris@18 314 }
Chris@18 315
Chris@18 316 PyPluginData *pd = getPluginData(pyPluginHandle);
Chris@18 317 if (!pd) return 0;
Chris@18 318
Chris@18 319 if (!pd->isInitialised) {
Chris@18 320 PyErr_SetString(PyExc_StandardError,
Chris@18 321 "Plugin has not been initialised");
Chris@18 322 return 0;
Chris@18 323 }
Chris@18 324
Chris@18 325 pd->plugin->reset();
Chris@18 326 return Py_True;
Chris@18 327 }
Chris@18 328
Chris@18 329 static PyObject *
Chris@20 330 vampyhost_getParameter(PyObject *self, PyObject *args)
Chris@20 331 {
Chris@20 332 PyObject *pyPluginHandle;
Chris@20 333 PyObject *pyParam;
Chris@20 334
Chris@20 335 if (!PyArg_ParseTuple(args, "OS", &pyPluginHandle, &pyParam)) {
Chris@20 336 PyErr_SetString(PyExc_TypeError,
Chris@20 337 "getParameter() takes plugin handle (object) and parameter id (string) arguments");
Chris@20 338 return 0; }
Chris@20 339
Chris@20 340 PyPluginData *pd = getPluginData(pyPluginHandle);
Chris@20 341 if (!pd) return 0;
Chris@20 342
Chris@20 343 float value = pd->plugin->getParameter(PyString_AS_STRING(pyParam));
Chris@20 344 return PyFloat_FromDouble(double(value));
Chris@20 345 }
Chris@20 346
Chris@20 347 static PyObject *
Chris@20 348 vampyhost_setParameter(PyObject *self, PyObject *args)
Chris@20 349 {
Chris@20 350 PyObject *pyPluginHandle;
Chris@20 351 PyObject *pyParam;
Chris@20 352 float value;
Chris@20 353
Chris@20 354 if (!PyArg_ParseTuple(args, "OSf", &pyPluginHandle, &pyParam, &value)) {
Chris@20 355 PyErr_SetString(PyExc_TypeError,
Chris@20 356 "setParameter() takes plugin handle (object), parameter id (string), and value (float) arguments");
Chris@20 357 return 0; }
Chris@20 358
Chris@20 359 PyPluginData *pd = getPluginData(pyPluginHandle);
Chris@20 360 if (!pd) return 0;
Chris@20 361
Chris@20 362 pd->plugin->setParameter(PyString_AS_STRING(pyParam), value);
Chris@20 363 return Py_True;
Chris@20 364 }
Chris@20 365
Chris@20 366 static PyObject *
Chris@0 367 vampyhost_process(PyObject *self, PyObject *args)
Chris@0 368 {
Chris@0 369 PyObject *pyPluginHandle;
Chris@0 370 PyObject *pyBuffer;
Chris@0 371 PyObject *pyRealTime;
Chris@0 372
luis@7 373 if (!PyArg_ParseTuple(args, "OOO",
Chris@0 374 &pyPluginHandle, // C object holding a pointer to a plugin and its descriptor
Chris@0 375 &pyBuffer, // Audio data
Chris@0 376 &pyRealTime)) { // TimeStamp
Chris@0 377 PyErr_SetString(PyExc_TypeError,
Chris@17 378 "process() takes plugin handle (object), buffer (2D array of channels * samples floats) and timestamp (RealTime) arguments");
Chris@16 379 return 0; }
Chris@0 380
Chris@0 381 if (!PyRealTime_Check(pyRealTime)) {
Chris@0 382 PyErr_SetString(PyExc_TypeError,"Valid timestamp required.");
Chris@16 383 return 0; }
Chris@0 384
Chris@17 385 if (!PyList_Check(pyBuffer)) {
Chris@17 386 PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input.");
Chris@17 387 return 0;
Chris@17 388 }
Chris@17 389
Chris@16 390 PyPluginData *pd = getPluginData(pyPluginHandle);
Chris@16 391 if (!pd) return 0;
Chris@0 392
Chris@0 393 if (!pd->isInitialised) {
Chris@0 394 PyErr_SetString(PyExc_StandardError,
Chris@0 395 "Plugin has not been initialised.");
Chris@16 396 return 0;
Chris@16 397 }
Chris@0 398
Chris@12 399 int channels = pd->channels;
Chris@0 400
Chris@4 401 if (PyList_GET_SIZE(pyBuffer) != channels) {
Chris@17 402 cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << endl;
Chris@4 403 PyErr_SetString(PyExc_TypeError, "Wrong number of channels");
Chris@16 404 return 0;
Chris@4 405 }
Chris@0 406
Chris@4 407 float **inbuf = new float *[channels];
Chris@0 408
Chris@12 409 PyTypeConversions typeConv;
Chris@12 410 typeConv.setNumpyInstalled(true);
Chris@17 411
Chris@17 412 cerr << "here!" << endl;
Chris@12 413
Chris@12 414 vector<vector<float> > data;
Chris@4 415 for (int c = 0; c < channels; ++c) {
Chris@4 416 PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c);
Chris@17 417 data.push_back(typeConv.PyValue_To_FloatVector(cbuf));
Chris@12 418 }
Chris@12 419
Chris@12 420 for (int c = 0; c < channels; ++c) {
Chris@17 421 if (data[c].size() != pd->blockSize) {
Chris@17 422 cerr << "Wrong number of samples on channel " << c << ": expected " << pd->blockSize << " (plugin's block size), got " << data[c].size() << endl;
Chris@17 423 PyErr_SetString(PyExc_TypeError, "Wrong number of samples");
Chris@17 424 return 0;
Chris@17 425 }
Chris@12 426 inbuf[c] = &data[c][0];
Chris@4 427 }
Chris@0 428
Chris@17 429 cerr << "no, here!" << endl;
Chris@17 430
Chris@12 431 RealTime timeStamp = *PyRealTime_AsRealTime(pyRealTime);
Chris@0 432
Chris@18 433 cerr << "no no, here!" << endl;
Chris@0 434
Chris@18 435 Plugin::FeatureSet fs = pd->plugin->process(inbuf, timeStamp);
Chris@0 436
Chris@4 437 delete[] inbuf;
Chris@0 438
Chris@18 439 cerr << "no no no, here!" << endl;
Chris@18 440
Chris@18 441 PyTypeConversions conv;
Chris@18 442 conv.setNumpyInstalled(true);
Chris@18 443
Chris@18 444 PyObject *pyFs = PyDict_New();
Chris@0 445
Chris@18 446 for (Plugin::FeatureSet::const_iterator fsi = fs.begin();
Chris@18 447 fsi != fs.end(); ++fsi) {
Chris@18 448
Chris@18 449 int fno = fsi->first;
Chris@18 450 const Plugin::FeatureList &fl = fsi->second;
Chris@18 451
Chris@18 452 if (!fl.empty()) {
Chris@18 453
Chris@18 454 PyObject *pyFl = PyList_New(fl.size());
Chris@18 455
Chris@18 456 for (int fli = 0; fli < (int)fl.size(); ++fli) {
Chris@18 457
Chris@18 458 const Plugin::Feature &f = fl[fli];
Chris@18 459 PyObject *pyF = PyDict_New();
Chris@18 460
Chris@18 461 if (f.hasTimestamp) {
Chris@18 462 PyDict_SetItemString
Chris@18 463 (pyF, "timestamp", PyRealTime_FromRealTime(f.timestamp));
Chris@18 464 }
Chris@18 465 if (f.hasDuration) {
Chris@18 466 PyDict_SetItemString
Chris@18 467 (pyF, "duration", PyRealTime_FromRealTime(f.duration));
Chris@18 468 }
Chris@18 469
Chris@18 470 PyDict_SetItemString
Chris@18 471 (pyF, "label", PyString_FromString(f.label.c_str()));
Chris@18 472
Chris@18 473 if (!f.values.empty()) {
Chris@18 474 PyDict_SetItemString
Chris@18 475 (pyF, "values", conv.FloatVector_To_PyArray(f.values));
Chris@18 476 }
Chris@18 477
Chris@18 478 PyList_SET_ITEM(pyFl, fli, pyF);
Chris@18 479 }
Chris@18 480
Chris@18 481 PyObject *pyN = PyInt_FromLong(fno);
Chris@18 482 PyDict_SetItem(pyFs, pyN, pyFl);
Chris@18 483 }
Chris@18 484 }
Chris@18 485
Chris@18 486 cerr << "no you fool, here!" << endl;
Chris@18 487
Chris@18 488 return pyFs;
Chris@0 489 }
Chris@0 490
Chris@0 491
Chris@18 492 // module methods table
Chris@0 493 static PyMethodDef vampyhost_methods[] = {
Chris@0 494
Chris@18 495 {"listPlugins", vampyhost_enumeratePlugins, METH_NOARGS,
Chris@0 496 xx_foo_doc},
Chris@0 497
Chris@15 498 {"getPluginPath", vampyhost_getPluginPath, METH_NOARGS,
Chris@15 499 xx_foo_doc},
Chris@15 500
Chris@18 501 {"getCategoryOf", vampyhost_getPluginCategory, METH_VARARGS,
Chris@0 502 xx_foo_doc},
Chris@0 503
Chris@18 504 {"getLibraryFor", vampyhost_getLibraryFor, METH_VARARGS,
Chris@0 505 xx_foo_doc},
Chris@0 506
Chris@18 507 {"getOutputsOf", vampyhost_getOutputList, METH_VARARGS,
Chris@0 508 xx_foo_doc},
Chris@0 509
Chris@0 510 {"loadPlugin", vampyhost_loadPlugin, METH_VARARGS,
Chris@0 511 xx_foo_doc},
Chris@0 512
Chris@20 513 {"getParameter", vampyhost_getParameter, METH_VARARGS,
Chris@20 514 xx_foo_doc},
Chris@20 515
Chris@20 516 {"setParameter", vampyhost_setParameter, METH_VARARGS,
Chris@20 517 xx_foo_doc},
Chris@20 518
Chris@18 519 {"initialise", vampyhost_initialise, METH_VARARGS,
Chris@18 520 xx_foo_doc},
Chris@18 521
Chris@18 522 {"reset", vampyhost_reset, METH_VARARGS,
Chris@18 523 xx_foo_doc},
Chris@18 524
Chris@0 525 {"process", vampyhost_process, METH_VARARGS,
Chris@0 526 xx_foo_doc},
Chris@0 527
Chris@0 528 {"unloadPlugin", vampyhost_unloadPlugin, METH_VARARGS,
Chris@0 529 xx_foo_doc},
Chris@0 530
Chris@16 531 {0, 0} /* sentinel */
Chris@0 532 };
Chris@0 533
Chris@0 534 //Documentation for our new module
Chris@0 535 PyDoc_STRVAR(module_doc, "This is a template module just for instruction.");
Chris@0 536
Chris@14 537
Chris@14 538
Chris@0 539 /* Initialization function for the module (*must* be called initxx) */
Chris@0 540
Chris@0 541 //module initialization (includes extern C {...} as necessary)
Chris@0 542 PyMODINIT_FUNC
Chris@0 543 initvampyhost(void)
Chris@0 544 {
Chris@0 545 PyObject *m;
Chris@0 546
Chris@0 547 /* Finalize the type object including setting type of the new type
luis@7 548 * object; doing it here is required for portability to Windows
Chris@0 549 * without requiring C++. */
Chris@0 550
Chris@0 551 if (PyType_Ready(&RealTime_Type) < 0)
Chris@0 552 return;
Chris@0 553
Chris@0 554 /* Create the module and add the functions */
Chris@0 555 m = Py_InitModule3("vampyhost", vampyhost_methods, module_doc);
Chris@16 556 if (!m) return;
Chris@0 557
Chris@14 558 import_array();
Chris@14 559
Chris@17 560 PyModule_AddObject(m, "RealTime", (PyObject *)&RealTime_Type);
Chris@0 561 }