annotate vampyhost.cpp @ 18:4b9adb4b532f

Return values from process
author Chris Cannam
date Tue, 25 Nov 2014 09:58:25 +0000
parents 3893b76daf80
children 8e5cefa70c99
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@15 226 "loadPlugin() takes plugin key (string) and sample rate (number) 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@0 330 vampyhost_process(PyObject *self, PyObject *args)
Chris@0 331 {
Chris@0 332 PyObject *pyPluginHandle;
Chris@0 333 PyObject *pyBuffer;
Chris@0 334 PyObject *pyRealTime;
Chris@0 335
luis@7 336 if (!PyArg_ParseTuple(args, "OOO",
Chris@0 337 &pyPluginHandle, // C object holding a pointer to a plugin and its descriptor
Chris@0 338 &pyBuffer, // Audio data
Chris@0 339 &pyRealTime)) { // TimeStamp
Chris@0 340 PyErr_SetString(PyExc_TypeError,
Chris@17 341 "process() takes plugin handle (object), buffer (2D array of channels * samples floats) and timestamp (RealTime) arguments");
Chris@16 342 return 0; }
Chris@0 343
Chris@0 344 if (!PyRealTime_Check(pyRealTime)) {
Chris@0 345 PyErr_SetString(PyExc_TypeError,"Valid timestamp required.");
Chris@16 346 return 0; }
Chris@0 347
Chris@17 348 if (!PyList_Check(pyBuffer)) {
Chris@17 349 PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input.");
Chris@17 350 return 0;
Chris@17 351 }
Chris@17 352
Chris@16 353 PyPluginData *pd = getPluginData(pyPluginHandle);
Chris@16 354 if (!pd) return 0;
Chris@0 355
Chris@0 356 if (!pd->isInitialised) {
Chris@0 357 PyErr_SetString(PyExc_StandardError,
Chris@0 358 "Plugin has not been initialised.");
Chris@16 359 return 0;
Chris@16 360 }
Chris@0 361
Chris@12 362 int channels = pd->channels;
Chris@0 363
Chris@4 364 if (PyList_GET_SIZE(pyBuffer) != channels) {
Chris@17 365 cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << endl;
Chris@4 366 PyErr_SetString(PyExc_TypeError, "Wrong number of channels");
Chris@16 367 return 0;
Chris@4 368 }
Chris@0 369
Chris@4 370 float **inbuf = new float *[channels];
Chris@0 371
Chris@12 372 PyTypeConversions typeConv;
Chris@12 373 typeConv.setNumpyInstalled(true);
Chris@17 374
Chris@17 375 cerr << "here!" << endl;
Chris@12 376
Chris@12 377 vector<vector<float> > data;
Chris@4 378 for (int c = 0; c < channels; ++c) {
Chris@4 379 PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c);
Chris@17 380 data.push_back(typeConv.PyValue_To_FloatVector(cbuf));
Chris@12 381 }
Chris@12 382
Chris@12 383 for (int c = 0; c < channels; ++c) {
Chris@17 384 if (data[c].size() != pd->blockSize) {
Chris@17 385 cerr << "Wrong number of samples on channel " << c << ": expected " << pd->blockSize << " (plugin's block size), got " << data[c].size() << endl;
Chris@17 386 PyErr_SetString(PyExc_TypeError, "Wrong number of samples");
Chris@17 387 return 0;
Chris@17 388 }
Chris@12 389 inbuf[c] = &data[c][0];
Chris@4 390 }
Chris@0 391
Chris@17 392 cerr << "no, here!" << endl;
Chris@17 393
Chris@12 394 RealTime timeStamp = *PyRealTime_AsRealTime(pyRealTime);
Chris@0 395
Chris@18 396 cerr << "no no, here!" << endl;
Chris@0 397
Chris@18 398 Plugin::FeatureSet fs = pd->plugin->process(inbuf, timeStamp);
Chris@0 399
Chris@4 400 delete[] inbuf;
Chris@0 401
Chris@18 402 cerr << "no no no, here!" << endl;
Chris@18 403
Chris@18 404 PyTypeConversions conv;
Chris@18 405 conv.setNumpyInstalled(true);
Chris@18 406
Chris@18 407 PyObject *pyFs = PyDict_New();
Chris@0 408
Chris@18 409 for (Plugin::FeatureSet::const_iterator fsi = fs.begin();
Chris@18 410 fsi != fs.end(); ++fsi) {
Chris@18 411
Chris@18 412 int fno = fsi->first;
Chris@18 413 const Plugin::FeatureList &fl = fsi->second;
Chris@18 414
Chris@18 415 if (!fl.empty()) {
Chris@18 416
Chris@18 417 PyObject *pyFl = PyList_New(fl.size());
Chris@18 418
Chris@18 419 for (int fli = 0; fli < (int)fl.size(); ++fli) {
Chris@18 420
Chris@18 421 const Plugin::Feature &f = fl[fli];
Chris@18 422 PyObject *pyF = PyDict_New();
Chris@18 423
Chris@18 424 if (f.hasTimestamp) {
Chris@18 425 PyDict_SetItemString
Chris@18 426 (pyF, "timestamp", PyRealTime_FromRealTime(f.timestamp));
Chris@18 427 }
Chris@18 428 if (f.hasDuration) {
Chris@18 429 PyDict_SetItemString
Chris@18 430 (pyF, "duration", PyRealTime_FromRealTime(f.duration));
Chris@18 431 }
Chris@18 432
Chris@18 433 PyDict_SetItemString
Chris@18 434 (pyF, "label", PyString_FromString(f.label.c_str()));
Chris@18 435
Chris@18 436 if (!f.values.empty()) {
Chris@18 437 PyDict_SetItemString
Chris@18 438 (pyF, "values", conv.FloatVector_To_PyArray(f.values));
Chris@18 439 }
Chris@18 440
Chris@18 441 PyList_SET_ITEM(pyFl, fli, pyF);
Chris@18 442 }
Chris@18 443
Chris@18 444 PyObject *pyN = PyInt_FromLong(fno);
Chris@18 445 PyDict_SetItem(pyFs, pyN, pyFl);
Chris@18 446 }
Chris@18 447 }
Chris@18 448
Chris@18 449 cerr << "no you fool, here!" << endl;
Chris@18 450
Chris@18 451 return pyFs;
Chris@0 452 }
Chris@0 453
Chris@17 454 #ifdef NOPE
Chris@0 455 static PyObject *
Chris@0 456 vampyhost_getOutput(PyObject *self, PyObject *args) {
Chris@0 457
Chris@0 458 PyObject *pyPluginHandle;
Chris@0 459 // PyObject *pyBuffer;
Chris@0 460 // PyObject *pyRealTime;
Chris@0 461 PyObject *pyOutput;
Chris@0 462
luis@7 463 if (!PyArg_ParseTuple(args, "OO",
Chris@0 464 &pyPluginHandle, // C object holding a pointer to a plugin and its descriptor
Chris@0 465 &pyOutput)) { // Output reference
Chris@0 466 PyErr_SetString(PyExc_TypeError,
Chris@0 467 "Required: plugin handle, buffer, timestmap.");
Chris@16 468 return 0; }
Chris@0 469
Chris@16 470 PyPluginData *pd = getPluginData(pyPluginHandle);
Chris@16 471 if (!pd) return 0;
Chris@0 472
Chris@0 473 unsigned int outputNo = (unsigned int) PyInt_AS_LONG(pyOutput);
Chris@0 474
Chris@0 475 //Get output list: but we don't need it
Chris@0 476 //Plugin::FeatureList features = pd->output[outputNo];
Chris@0 477
Chris@0 478 size_t outLength = pd->output[outputNo].size();
Chris@0 479
Chris@0 480 //New PyList for the featurelist
Chris@0 481 PyObject *pyFeatureList = PyList_New(outLength);
Chris@0 482
Chris@0 483 for (size_t i = 0; i < outLength; ++i) {
Chris@0 484 // Test:
Chris@0 485 /*
luis@7 486 XxoObject *pyFeature = PyObject_New(XxoObject, &Xxo_Type);
Chris@16 487 if (pyFeature == 0) break; //return 0;
Chris@0 488
Chris@16 489 pyFeature->x_attr = 0;
Chris@0 490 pyFeature->feature = &pd->output[outputNo][i];
Chris@0 491
luis@7 492 PyList_SET_ITEM(pyFeatureList,i,(PyObject*)pyFeature);
Chris@0 493 */
Chris@0 494 }
Chris@0 495
Chris@0 496 Py_INCREF(pyFeatureList);
Chris@0 497 return pyFeatureList;
Chris@0 498
Chris@0 499 // EXPLAIN WHAT WE NEED TO DO HERE:
Chris@0 500 // We have the block output in pd->output
luis@7 501 // FeatureSet[output] -> [Feature[x]] -> Feature.hasTimestamp = v
luis@7 502 // Vamp::Plugin::FeatureSet output; = pd->output
Chris@17 503 // typedef vector<Feature> FeatureList;
Chris@17 504 // typedef map<int, FeatureList> FeatureSet; // key is output no
Chris@0 505
luis@7 506 // THIS IS FOR OUTPUT id LOOKUP LATER
Chris@0 507 // Plugin::OutputList outputs = plugin->getOutputDescriptors();
luis@7 508 //
Chris@0 509 // if (outputs.size()<1) {
Chris@0 510 // string pyerr("Plugin has no output: "); pyerr += pluginKey;
luis@7 511 // PyErr_SetString(PyExc_TypeError,pyerr.c_str());
Chris@16 512 // return 0;
Chris@0 513 // }
luis@7 514 //
Chris@0 515 // //New list object
Chris@0 516 // PyObject *pyList = PyList_New(outputs.size());
luis@7 517 //
Chris@0 518 // for (size_t i = 0; i < outputs.size(); ++i) {
luis@7 519 // PyObject *pyOutputId =
Chris@0 520 // PyString_FromString(outputs[i].identifier.c_str());
luis@7 521 // PyList_SET_ITEM(pyList,i,pyOutputId);
Chris@0 522 // }
luis@7 523
Chris@0 524 }
Chris@17 525 #endif
Chris@0 526
Chris@0 527
Chris@18 528 // module methods table
Chris@0 529 static PyMethodDef vampyhost_methods[] = {
Chris@0 530
Chris@18 531 {"listPlugins", vampyhost_enumeratePlugins, METH_NOARGS,
Chris@0 532 xx_foo_doc},
Chris@0 533
Chris@15 534 {"getPluginPath", vampyhost_getPluginPath, METH_NOARGS,
Chris@15 535 xx_foo_doc},
Chris@15 536
Chris@18 537 {"getCategoryOf", vampyhost_getPluginCategory, METH_VARARGS,
Chris@0 538 xx_foo_doc},
Chris@0 539
Chris@18 540 {"getLibraryFor", vampyhost_getLibraryFor, METH_VARARGS,
Chris@0 541 xx_foo_doc},
Chris@0 542
Chris@18 543 {"getOutputsOf", vampyhost_getOutputList, METH_VARARGS,
Chris@0 544 xx_foo_doc},
Chris@0 545
Chris@0 546 {"loadPlugin", vampyhost_loadPlugin, METH_VARARGS,
Chris@0 547 xx_foo_doc},
Chris@0 548
Chris@18 549 {"initialise", vampyhost_initialise, METH_VARARGS,
Chris@18 550 xx_foo_doc},
Chris@18 551
Chris@18 552 {"reset", vampyhost_reset, METH_VARARGS,
Chris@18 553 xx_foo_doc},
Chris@18 554
Chris@0 555 {"process", vampyhost_process, METH_VARARGS,
Chris@0 556 xx_foo_doc},
Chris@0 557
Chris@0 558 {"unloadPlugin", vampyhost_unloadPlugin, METH_VARARGS,
Chris@0 559 xx_foo_doc},
Chris@0 560
Chris@16 561 {0, 0} /* sentinel */
Chris@0 562 };
Chris@0 563
Chris@0 564 //Documentation for our new module
Chris@0 565 PyDoc_STRVAR(module_doc, "This is a template module just for instruction.");
Chris@0 566
Chris@14 567
Chris@14 568
Chris@0 569 /* Initialization function for the module (*must* be called initxx) */
Chris@0 570
Chris@0 571 //module initialization (includes extern C {...} as necessary)
Chris@0 572 PyMODINIT_FUNC
Chris@0 573 initvampyhost(void)
Chris@0 574 {
Chris@0 575 PyObject *m;
Chris@0 576
Chris@0 577 /* Finalize the type object including setting type of the new type
luis@7 578 * object; doing it here is required for portability to Windows
Chris@0 579 * without requiring C++. */
Chris@0 580
Chris@0 581 if (PyType_Ready(&RealTime_Type) < 0)
Chris@0 582 return;
Chris@0 583
Chris@0 584 /* Create the module and add the functions */
Chris@0 585 m = Py_InitModule3("vampyhost", vampyhost_methods, module_doc);
Chris@16 586 if (!m) return;
Chris@0 587
Chris@14 588 import_array();
Chris@14 589
Chris@17 590 PyModule_AddObject(m, "RealTime", (PyObject *)&RealTime_Type);
Chris@0 591 }