annotate vampyhost.cpp @ 21:4b4a7ec1080d

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