annotate vampyhost.cpp @ 15:8b264cabbc28

Start to tidy & rationalise the API
author Chris Cannam
date Mon, 24 Nov 2014 11:02:28 +0000
parents 8565ec421f9c
children 7987e3123909
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@14 13 #include "PyTypeConversions.h"
Chris@14 14 #include "PyRealTime.h"
Chris@0 15
Chris@4 16 //!!! NB all our NumPy stuff is currently using the deprecated API --
Chris@4 17 //!!! need to work out how to update this
Chris@12 18 //#include "numpy/arrayobject.h"
Chris@12 19
Chris@12 20 #define HAVE_NUMPY 1 // Required
Chris@12 21
Chris@0 22 //includes for vamp host
Chris@1 23 #include "vamp-hostsdk/Plugin.h"
Chris@1 24 #include "vamp-hostsdk/PluginHostAdapter.h"
Chris@1 25 #include "vamp-hostsdk/PluginChannelAdapter.h"
Chris@1 26 #include "vamp-hostsdk/PluginInputDomainAdapter.h"
Chris@1 27 #include "vamp-hostsdk/PluginLoader.h"
Chris@0 28 //#include "vamp/vamp.h"
Chris@0 29
Chris@0 30 #include <iostream>
Chris@0 31 #include <fstream>
Chris@0 32 #include <set>
Chris@0 33 #include <sndfile.h>
Chris@0 34
Chris@0 35 #include <cstring>
Chris@0 36 #include <cstdlib>
Chris@0 37 #include <string>
Chris@0 38
Chris@0 39 #include "system.h"
Chris@0 40
Chris@0 41 #include <cmath>
Chris@0 42
Chris@0 43
Chris@0 44 using namespace std;
Chris@0 45 using namespace Vamp;
Chris@0 46
Chris@0 47 using Vamp::Plugin;
Chris@0 48 using Vamp::PluginHostAdapter;
Chris@0 49 using Vamp::RealTime;
Chris@0 50 using Vamp::HostExt::PluginLoader;
Chris@0 51
Chris@0 52 #define HOST_VERSION "1.1"
Chris@0 53
Chris@0 54
Chris@0 55 /* MODULE HELPER FUNCTIONS */
Chris@2 56 PyDoc_STRVAR(xx_foo_doc, "Some description"); //!!!
Chris@0 57
Chris@0 58 /*obtain C plugin handle and key from pyCobject */
luis@7 59 bool getPluginHandle
Chris@0 60 (PyObject *pyPluginHandle, Plugin **plugin, string **pKey=NULL) {
Chris@0 61
Chris@0 62 //char errormsg[]="Wrong input argument: Plugin Handle required.";
Chris@0 63
Chris@0 64 *plugin = NULL;
Chris@2 65 if (!PyCObject_Check(pyPluginHandle)) return false;
Chris@0 66
Chris@0 67 //try to convert to Plugin pointer
Chris@0 68 Plugin *p = (Plugin*) PyCObject_AsVoidPtr(pyPluginHandle);
luis@7 69 if (!p) return false;
Chris@0 70
Chris@0 71 string pId;
Chris@0 72
Chris@0 73 if (pKey) {
Chris@0 74 *pKey = (string*) PyCObject_GetDesc(pyPluginHandle);
Chris@2 75 if (!*pKey) return false;
Chris@0 76 pId = *(string*) *pKey;
Chris@0 77
Chris@0 78 } else {
Chris@0 79
Chris@0 80 void *pKey = PyCObject_GetDesc(pyPluginHandle);
Chris@2 81 if (!pKey) return false;
Chris@0 82 pId = *(string*) pKey;
Chris@0 83 }
luis@7 84
Chris@0 85 string::size_type pos = pId.find(':');
Chris@2 86 if (pos == string::npos) return false;
Chris@0 87
Chris@0 88 pId = pId.substr(pId.rfind(':')+1);
luis@7 89 string identifier = p->getIdentifier();
luis@7 90
Chris@2 91 if (pId.compare(identifier)) return false;
Chris@0 92
Chris@0 93 *plugin = p;
Chris@0 94 return true;
Chris@0 95 }
Chris@0 96
Chris@0 97 /*
Chris@0 98 ----------------------------------------------------------------
Chris@0 99 */
Chris@0 100
Chris@0 101
Chris@0 102
Chris@0 103 /*
luis@7 104 VAMPYHOST MAIN
luis@7 105 ---------------------------------------------------------------------
Chris@0 106 */
Chris@0 107
Chris@0 108 static PyObject *
Chris@0 109 vampyhost_enumeratePlugins(PyObject *self, PyObject *args)
Chris@0 110 {
Chris@0 111 PluginLoader *loader = PluginLoader::getInstance();
Chris@0 112 vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
Chris@15 113 PyTypeConversions conv;
Chris@15 114 return conv.PyValue_From_StringVector(plugins);
Chris@0 115 }
Chris@0 116
Chris@15 117 static PyObject *
Chris@15 118 vampyhost_getPluginPath(PyObject *self, PyObject *args)
Chris@15 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@0 127 //convert to stl string
Chris@0 128 string pluginKey(PyString_AS_STRING(pyPluginKey));
Chris@0 129
Chris@0 130 //check pluginKey Validity
Chris@0 131 string::size_type ki = pluginKey.find(':');
Chris@0 132 if (ki == string::npos) {
Chris@0 133 PyErr_SetString(PyExc_TypeError,
Chris@15 134 "Plugin key must be of the form library:identifier");
Chris@15 135 return "";
Chris@0 136 }
Chris@0 137
Chris@15 138 return pluginKey;
Chris@15 139 }
Chris@15 140
Chris@15 141 static PyObject *
Chris@15 142 vampyhost_getLibraryFor(PyObject *self, PyObject *args)
Chris@15 143 {
Chris@15 144 PyObject *pyPluginKey;
Chris@15 145
Chris@15 146 if (!PyArg_ParseTuple(args, "S", &pyPluginKey)) {
Chris@15 147 PyErr_SetString(PyExc_TypeError,
Chris@15 148 "getLibraryPathForPlugin() takes plugin key (string) argument");
Chris@15 149 return NULL; }
Chris@15 150
Chris@15 151 string pluginKey = toPluginKey(pyPluginKey);
Chris@15 152 if (pluginKey == "") return NULL;
Chris@15 153
Chris@0 154 PluginLoader *loader = PluginLoader::getInstance();
Chris@0 155 string path = loader->getLibraryPathForPlugin(pluginKey);
Chris@0 156 PyObject *pyPath = PyString_FromString(path.c_str());
Chris@0 157 return pyPath;
Chris@0 158 }
Chris@0 159
Chris@0 160 static PyObject *
Chris@0 161 vampyhost_getPluginCategory(PyObject *self, PyObject *args)
Chris@0 162 {
Chris@0 163 PyObject *pyPluginKey;
Chris@0 164
Chris@0 165 if (!PyArg_ParseTuple(args, "S", &pyPluginKey)) {
Chris@0 166 PyErr_SetString(PyExc_TypeError,
Chris@15 167 "getPluginCategory() takes plugin key (string) argument");
Chris@0 168 return NULL; }
Chris@0 169
Chris@15 170 string pluginKey = toPluginKey(pyPluginKey);
Chris@15 171 if (pluginKey == "") return NULL;
Chris@0 172
Chris@0 173 PluginLoader *loader = PluginLoader::getInstance();
luis@7 174 PluginLoader::PluginCategoryHierarchy
Chris@0 175 category = loader->getPluginCategory(pluginKey);
Chris@0 176
Chris@15 177 PyTypeConversions conv;
Chris@15 178 return conv.PyValue_From_StringVector(category);
Chris@0 179 }
Chris@0 180
Chris@0 181 static PyObject *
Chris@0 182 vampyhost_getOutputList(PyObject *self, PyObject *args)
Chris@0 183 {
Chris@0 184 PyObject *pyPluginHandle;
Chris@15 185 Plugin::OutputList outputs;
Chris@0 186
Chris@0 187 if (!PyArg_ParseTuple(args, "O", &pyPluginHandle)) {
Chris@0 188 PyErr_SetString(PyExc_TypeError,
Chris@15 189 "getOutputList() takes plugin handle (object) or plugin key (string) argument");
luis@7 190 return NULL;
Chris@0 191 }
Chris@0 192
Chris@0 193 if (PyString_Check(pyPluginHandle) ) {
Chris@0 194
Chris@15 195 // we have a plugin key
Chris@0 196
Chris@15 197 string pluginKey = toPluginKey(pyPluginHandle);
Chris@15 198 if (pluginKey == "") return NULL;
Chris@15 199
Chris@15 200 PluginLoader *loader = PluginLoader::getInstance();
Chris@15 201
Chris@15 202 Plugin *plugin = loader->loadPlugin
Chris@15 203 (pluginKey, 48000, PluginLoader::ADAPT_ALL_SAFE);
Chris@15 204 if (!plugin) {
Chris@15 205 string pyerr("Failed to load plugin: "); pyerr += pluginKey;
Chris@15 206 PyErr_SetString(PyExc_TypeError,pyerr.c_str());
Chris@15 207 return NULL;
Chris@15 208 }
Chris@15 209
Chris@15 210 outputs = plugin->getOutputDescriptors();
Chris@15 211
Chris@15 212 delete plugin;
Chris@15 213
Chris@0 214 } else {
luis@7 215
Chris@15 216 // we have a loaded plugin handle
Chris@15 217
luis@7 218 string *key;
luis@7 219 Plugin *plugin;
Chris@0 220
Chris@0 221 if ( !getPluginHandle(pyPluginHandle, &plugin, &key) ) {
Chris@0 222 PyErr_SetString(PyExc_TypeError,
Chris@0 223 "Invalid or deleted plugin handle.");
Chris@0 224 return NULL; }
Chris@15 225
Chris@15 226 outputs = plugin->getOutputDescriptors();
luis@7 227 }
luis@7 228
Chris@0 229 PyObject *pyList = PyList_New(outputs.size());
Chris@0 230
Chris@0 231 for (size_t i = 0; i < outputs.size(); ++i) {
luis@7 232 PyObject *pyOutputId =
Chris@0 233 PyString_FromString(outputs[i].identifier.c_str());
Chris@15 234 PyList_SET_ITEM(pyList, i, pyOutputId);
Chris@0 235 }
Chris@0 236
Chris@0 237 return pyList;
Chris@0 238 }
Chris@0 239
Chris@0 240 static PyObject *
Chris@0 241 vampyhost_loadPlugin(PyObject *self, PyObject *args)
Chris@0 242 {
Chris@0 243 PyObject *pyPluginKey;
Chris@0 244 float inputSampleRate;
Chris@0 245
luis@7 246 if (!PyArg_ParseTuple(args, "Sf",
Chris@0 247 &pyPluginKey,
Chris@0 248 &inputSampleRate)) {
Chris@0 249 PyErr_SetString(PyExc_TypeError,
Chris@15 250 "loadPlugin() takes plugin key (string) and sample rate (number) arguments");
Chris@0 251 return NULL; }
Chris@0 252
Chris@15 253 string pluginKey = toPluginKey(pyPluginKey);
Chris@15 254 if (pluginKey == "") return NULL;
Chris@0 255
Chris@0 256 PluginLoader *loader = PluginLoader::getInstance();
luis@7 257
Chris@15 258 Plugin *plugin = loader->loadPlugin(pluginKey, inputSampleRate,
Chris@15 259 PluginLoader::ADAPT_ALL_SAFE);
luis@7 260 if (!plugin) {
Chris@0 261 string pyerr("Failed to load plugin: "); pyerr += pluginKey;
luis@7 262 PyErr_SetString(PyExc_TypeError,pyerr.c_str());
Chris@0 263 return NULL;
luis@7 264 }
Chris@15 265
Chris@0 266 PyPluginDescriptor *pd = new PyPluginDescriptor;
luis@7 267
Chris@0 268 pd->key = pluginKey;
Chris@0 269 pd->isInitialised = false;
Chris@0 270 pd->inputSampleRate = inputSampleRate;
luis@7 271
luis@7 272 PyObject *pyPluginHandle = PyCObject_FromVoidPtrAndDesc(
luis@7 273 (void*) plugin, (void*) pd, NULL);
luis@7 274
Chris@0 275 return pyPluginHandle;
Chris@0 276 }
Chris@0 277
Chris@0 278
Chris@0 279
Chris@0 280 /* UNLOAD PLUGIN */
Chris@0 281
Chris@0 282 static PyObject *
Chris@0 283 vampyhost_unloadPlugin(PyObject *self, PyObject *args)
Chris@0 284 {
Chris@0 285 PyObject *pyPluginHandle;
Chris@0 286
Chris@0 287 if (!PyArg_ParseTuple(args, "O", &pyPluginHandle)) {
Chris@0 288 PyErr_SetString(PyExc_TypeError,
Chris@0 289 "Wrong input argument: Plugin Handle required.");
Chris@0 290 return NULL; }
Chris@0 291
luis@7 292 string *key;
luis@7 293 Plugin *plugin;
Chris@0 294
Chris@0 295 if ( !getPluginHandle(pyPluginHandle, &plugin, &key) ) {
Chris@0 296 PyErr_SetString(PyExc_TypeError,
Chris@0 297 "Invalid or already deleted plugin handle.");
Chris@0 298 return NULL; }
Chris@0 299
Chris@0 300 /* Prevent repeated calls from causing segfault
Chris@0 301 sice it will fail type checking the 2nd time: */
Chris@0 302 PyCObject_SetVoidPtr(pyPluginHandle,NULL);
luis@7 303
Chris@0 304 PyPluginDescriptor *pd = (PyPluginDescriptor*) key;
luis@7 305
Chris@0 306 delete plugin;
Chris@0 307 delete pd;
Chris@0 308 return pyPluginHandle;
Chris@0 309
Chris@0 310 }
Chris@0 311
Chris@0 312
Chris@0 313 /* INITIALISE PLUGIN */
Chris@0 314
Chris@0 315 static PyObject *
Chris@0 316 vampyhost_initialise(PyObject *self, PyObject *args)
Chris@0 317 {
Chris@0 318 PyObject *pyPluginHandle;
luis@7 319 size_t channels, blockSize, stepSize;
Chris@0 320
luis@7 321 if (!PyArg_ParseTuple (args, "Onnn", &pyPluginHandle,
luis@7 322 (size_t) &channels,
luis@7 323 (size_t) &stepSize,
luis@7 324 (size_t) &blockSize))
Chris@0 325 {
Chris@0 326 PyErr_SetString(PyExc_TypeError,
Chris@0 327 "Wrong input arguments: requires a valid plugin handle,channels,stepSize,blockSize.");
luis@7 328 return NULL;
Chris@0 329 }
Chris@0 330
luis@7 331 Plugin *plugin;
luis@7 332 string *key;
Chris@0 333
Chris@0 334 if ( !getPluginHandle(pyPluginHandle, &plugin, &key) ) {
Chris@0 335 PyErr_SetString(PyExc_TypeError,
Chris@0 336 "Invalid plugin handle.");
Chris@0 337 return NULL; }
Chris@0 338
Chris@0 339 // here we cast the void pointer as PyPluginDescriptor instead of string
luis@7 340 PyPluginDescriptor *plugDesc = (PyPluginDescriptor*) key;
Chris@0 341
Chris@0 342 plugDesc->channels = channels;
Chris@0 343 plugDesc->stepSize = stepSize;
Chris@0 344 plugDesc->blockSize = blockSize;
Chris@3 345
Chris@0 346 if (!plugin->initialise(channels, stepSize, blockSize)) {
Chris@6 347 std::cerr << "Failed to initialise native plugin adapter with channels = " << channels << ", stepSize = " << stepSize << ", blockSize = " << blockSize << " and ADAPT_ALL_SAFE set" << std::endl;
Chris@0 348 PyErr_SetString(PyExc_TypeError,
Chris@0 349 "Plugin initialization failed.");
Chris@6 350 return NULL;
Chris@6 351 }
Chris@0 352
luis@7 353 plugDesc->identifier =
Chris@0 354 plugDesc->key.substr(plugDesc->key.rfind(':')+1);
Chris@0 355 plugDesc->isInitialised = true;
luis@7 356
Chris@0 357 return Py_True;
Chris@0 358 }
Chris@0 359
Chris@0 360 /* RUN PROCESS */
Chris@0 361
Chris@0 362 static PyObject *
Chris@0 363 vampyhost_process(PyObject *self, PyObject *args)
Chris@0 364 {
Chris@0 365 PyObject *pyPluginHandle;
Chris@0 366 PyObject *pyBuffer;
Chris@0 367 PyObject *pyRealTime;
Chris@0 368
luis@7 369 if (!PyArg_ParseTuple(args, "OOO",
Chris@0 370 &pyPluginHandle, // C object holding a pointer to a plugin and its descriptor
Chris@0 371 &pyBuffer, // Audio data
Chris@0 372 &pyRealTime)) { // TimeStamp
Chris@0 373 PyErr_SetString(PyExc_TypeError,
Chris@0 374 "Required: plugin handle, buffer, timestmap.");
Chris@0 375 return NULL; }
Chris@0 376
Chris@0 377 if (!PyRealTime_Check(pyRealTime)) {
Chris@0 378 PyErr_SetString(PyExc_TypeError,"Valid timestamp required.");
Chris@0 379 return NULL; }
Chris@0 380
Chris@4 381 string *key;
luis@7 382 Plugin *plugin;
Chris@0 383
Chris@4 384 if (!getPluginHandle(pyPluginHandle, &plugin, &key)) {
Chris@0 385 PyErr_SetString(PyExc_AttributeError,
Chris@0 386 "Invalid or already deleted plugin handle.");
Chris@4 387 return NULL;
Chris@4 388 }
Chris@0 389
Chris@0 390 PyPluginDescriptor *pd = (PyPluginDescriptor*) key;
Chris@0 391
Chris@0 392 if (!pd->isInitialised) {
Chris@0 393 PyErr_SetString(PyExc_StandardError,
Chris@0 394 "Plugin has not been initialised.");
Chris@0 395 return NULL; }
Chris@0 396
Chris@12 397 int channels = pd->channels;
Chris@12 398 // int blockSize = pd->blockSize;
Chris@0 399
Chris@4 400 if (!PyList_Check(pyBuffer)) {
Chris@4 401 PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input.");
Chris@4 402 return NULL;
Chris@0 403 }
Chris@0 404
Chris@4 405 if (PyList_GET_SIZE(pyBuffer) != channels) {
Chris@6 406 std::cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << std::endl;
Chris@4 407 PyErr_SetString(PyExc_TypeError, "Wrong number of channels");
Chris@4 408 return NULL;
Chris@4 409 }
Chris@0 410
Chris@4 411 float **inbuf = new float *[channels];
Chris@0 412
Chris@12 413 PyTypeConversions typeConv;
Chris@12 414 typeConv.setNumpyInstalled(true);
Chris@12 415
Chris@12 416 vector<vector<float> > data;
Chris@4 417 for (int c = 0; c < channels; ++c) {
Chris@4 418 PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c);
Chris@12 419 data.push_back(typeConv.PyArray_To_FloatVector(cbuf));
Chris@12 420 }
Chris@12 421
Chris@12 422 for (int c = 0; c < channels; ++c) {
Chris@12 423 inbuf[c] = &data[c][0];
Chris@4 424 }
Chris@0 425
Chris@12 426 RealTime timeStamp = *PyRealTime_AsRealTime(pyRealTime);
Chris@0 427
Chris@0 428 //Call process and store the output
Chris@4 429 pd->output = plugin->process(inbuf, timeStamp);
Chris@0 430
Chris@0 431 /* TODO: DO SOMETHONG WITH THE FEATURE SET HERE */
Chris@0 432 /// convert to appropriate python objects, reuse types and conversion utilities from Vampy ...
Chris@0 433
Chris@4 434 delete[] inbuf;
Chris@0 435
Chris@4 436 return NULL; //!!! Need to return actual features!
Chris@0 437
Chris@0 438 }
Chris@0 439
Chris@0 440 /* GET / SET OUTPUT */
Chris@0 441
Chris@0 442 //getOutput(plugin,outputNo)
Chris@0 443 static PyObject *
Chris@0 444 vampyhost_getOutput(PyObject *self, PyObject *args) {
Chris@0 445
Chris@0 446 PyObject *pyPluginHandle;
Chris@0 447 // PyObject *pyBuffer;
Chris@0 448 // PyObject *pyRealTime;
Chris@0 449 PyObject *pyOutput;
Chris@0 450
luis@7 451 if (!PyArg_ParseTuple(args, "OO",
Chris@0 452 &pyPluginHandle, // C object holding a pointer to a plugin and its descriptor
Chris@0 453 &pyOutput)) { // Output reference
Chris@0 454 PyErr_SetString(PyExc_TypeError,
Chris@0 455 "Required: plugin handle, buffer, timestmap.");
Chris@0 456 return NULL; }
Chris@0 457
luis@7 458 string *key;
luis@7 459 Plugin *plugin;
Chris@0 460
Chris@0 461 if ( !getPluginHandle(pyPluginHandle, &plugin, &key) ) {
Chris@0 462 PyErr_SetString(PyExc_AttributeError,
Chris@0 463 "Invalid or already deleted plugin handle.");
Chris@0 464 return NULL; }
Chris@0 465
Chris@0 466 PyPluginDescriptor *pd = (PyPluginDescriptor*) key;
Chris@0 467
Chris@0 468 unsigned int outputNo = (unsigned int) PyInt_AS_LONG(pyOutput);
Chris@0 469
Chris@0 470 //Get output list: but we don't need it
Chris@0 471 //Plugin::FeatureList features = pd->output[outputNo];
Chris@0 472
Chris@0 473 size_t outLength = pd->output[outputNo].size();
Chris@0 474
Chris@0 475 //New PyList for the featurelist
Chris@0 476 PyObject *pyFeatureList = PyList_New(outLength);
Chris@0 477
Chris@0 478 for (size_t i = 0; i < outLength; ++i) {
Chris@0 479 // Test:
Chris@0 480 /*
luis@7 481 XxoObject *pyFeature = PyObject_New(XxoObject, &Xxo_Type);
Chris@0 482 if (pyFeature == NULL) break; //return NULL;
Chris@0 483
Chris@0 484 pyFeature->x_attr = NULL;
Chris@0 485 pyFeature->feature = &pd->output[outputNo][i];
Chris@0 486
luis@7 487 PyList_SET_ITEM(pyFeatureList,i,(PyObject*)pyFeature);
Chris@0 488 */
Chris@0 489 }
Chris@0 490
Chris@0 491 Py_INCREF(pyFeatureList);
Chris@0 492 return pyFeatureList;
Chris@0 493
Chris@0 494 // EXPLAIN WHAT WE NEED TO DO HERE:
Chris@0 495 // We have the block output in pd->output
luis@7 496 // FeatureSet[output] -> [Feature[x]] -> Feature.hasTimestamp = v
luis@7 497 // Vamp::Plugin::FeatureSet output; = pd->output
Chris@0 498 // typedef std::vector<Feature> FeatureList;
Chris@0 499 // typedef std::map<int, FeatureList> FeatureSet; // key is output no
Chris@0 500
luis@7 501 // THIS IS FOR OUTPUT id LOOKUP LATER
Chris@0 502 // Plugin::OutputList outputs = plugin->getOutputDescriptors();
luis@7 503 //
Chris@0 504 // if (outputs.size()<1) {
Chris@0 505 // string pyerr("Plugin has no output: "); pyerr += pluginKey;
luis@7 506 // PyErr_SetString(PyExc_TypeError,pyerr.c_str());
Chris@0 507 // return NULL;
Chris@0 508 // }
luis@7 509 //
Chris@0 510 // //New list object
Chris@0 511 // PyObject *pyList = PyList_New(outputs.size());
luis@7 512 //
Chris@0 513 // for (size_t i = 0; i < outputs.size(); ++i) {
luis@7 514 // PyObject *pyOutputId =
Chris@0 515 // PyString_FromString(outputs[i].identifier.c_str());
luis@7 516 // PyList_SET_ITEM(pyList,i,pyOutputId);
Chris@0 517 // }
luis@7 518
Chris@0 519 }
Chris@0 520
Chris@0 521
Chris@0 522
Chris@0 523
Chris@0 524 /* List of functions defined in this module */
Chris@0 525 //module methods table
Chris@0 526 static PyMethodDef vampyhost_methods[] = {
Chris@0 527
Chris@15 528 {"enumeratePlugins", vampyhost_enumeratePlugins, METH_NOARGS,
Chris@0 529 xx_foo_doc},
Chris@0 530
Chris@15 531 {"getPluginPath", vampyhost_getPluginPath, METH_NOARGS,
Chris@15 532 xx_foo_doc},
Chris@15 533
Chris@15 534 {"getLibraryForPlugin", vampyhost_getLibraryFor, METH_VARARGS,
Chris@0 535 xx_foo_doc},
Chris@0 536
Chris@0 537 {"getPluginCategory", vampyhost_getPluginCategory, METH_VARARGS,
Chris@0 538 xx_foo_doc},
Chris@0 539
Chris@0 540 {"getOutputList", vampyhost_getOutputList, METH_VARARGS,
Chris@0 541 xx_foo_doc},
Chris@0 542
Chris@0 543 {"loadPlugin", vampyhost_loadPlugin, METH_VARARGS,
Chris@0 544 xx_foo_doc},
Chris@0 545
Chris@0 546 {"process", vampyhost_process, METH_VARARGS,
Chris@0 547 xx_foo_doc},
Chris@0 548
Chris@0 549 {"unloadPlugin", vampyhost_unloadPlugin, METH_VARARGS,
Chris@0 550 xx_foo_doc},
Chris@0 551
Chris@0 552 {"initialise", vampyhost_initialise, METH_VARARGS,
Chris@0 553 xx_foo_doc},
Chris@0 554
Chris@0 555 {"getOutput", vampyhost_getOutput, METH_VARARGS,
Chris@0 556 xx_foo_doc},
Chris@0 557
Chris@0 558 /* Add RealTime Module Methods */
Chris@12 559 /*
Chris@0 560 {"frame2RealTime", (PyCFunction)RealTime_frame2RealTime, METH_VARARGS,
Chris@0 561 PyDoc_STR("frame2RealTime((int64)frame, (uint32)sampleRate ) -> returns new RealTime object from frame.")},
Chris@0 562
Chris@0 563 {"realtime", (PyCFunction)RealTime_new, METH_VARARGS,
Chris@0 564 PyDoc_STR("realtime() -> returns new RealTime object")},
Chris@12 565 */
Chris@0 566 {NULL, NULL} /* sentinel */
Chris@0 567 };
Chris@0 568
Chris@0 569 //Documentation for our new module
Chris@0 570 PyDoc_STRVAR(module_doc, "This is a template module just for instruction.");
Chris@0 571
Chris@14 572
Chris@14 573
Chris@0 574 /* Initialization function for the module (*must* be called initxx) */
Chris@0 575
Chris@0 576 //module initialization (includes extern C {...} as necessary)
Chris@0 577 PyMODINIT_FUNC
Chris@0 578 initvampyhost(void)
Chris@0 579 {
Chris@0 580 PyObject *m;
Chris@0 581
Chris@0 582 /* Finalize the type object including setting type of the new type
luis@7 583 * object; doing it here is required for portability to Windows
Chris@0 584 * without requiring C++. */
Chris@0 585
Chris@0 586 if (PyType_Ready(&RealTime_Type) < 0)
Chris@0 587 return;
Chris@0 588 // PyModule_AddObject(m, "Real_Time", (PyObject *)&RealTime_Type);
Chris@0 589
Chris@0 590 /* Create the module and add the functions */
Chris@0 591 m = Py_InitModule3("vampyhost", vampyhost_methods, module_doc);
Chris@0 592 if (m == NULL) return;
Chris@0 593
Chris@14 594 import_array();
Chris@14 595
Chris@0 596 // PyModule_AddObject(m, "realtime", (PyObject *)&RealTime_Type);
Chris@0 597
Chris@0 598 }