Mercurial > hg > vampy-host
comparison vampyhost.cpp @ 16:7987e3123909
Rationalise plugin handle management
author | Chris Cannam |
---|---|
date | Mon, 24 Nov 2014 14:39:56 +0000 |
parents | 8b264cabbc28 |
children | 3893b76daf80 |
comparison
equal
deleted
inserted
replaced
15:8b264cabbc28 | 16:7987e3123909 |
---|---|
7 #define PY_ARRAY_UNIQUE_SYMBOL VAMPY_ARRAY_API | 7 #define PY_ARRAY_UNIQUE_SYMBOL VAMPY_ARRAY_API |
8 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION | 8 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION |
9 #include "numpy/arrayobject.h" | 9 #include "numpy/arrayobject.h" |
10 | 10 |
11 #include <vampyhost.h> | 11 #include <vampyhost.h> |
12 | |
13 #include "PyTypeConversions.h" | |
14 #include "PyRealTime.h" | |
15 | |
16 //!!! NB all our NumPy stuff is currently using the deprecated API -- | |
17 //!!! need to work out how to update this | |
18 //#include "numpy/arrayobject.h" | |
19 | 12 |
20 #define HAVE_NUMPY 1 // Required | 13 #define HAVE_NUMPY 1 // Required |
21 | 14 |
22 //includes for vamp host | 15 //includes for vamp host |
23 #include "vamp-hostsdk/Plugin.h" | 16 #include "vamp-hostsdk/Plugin.h" |
24 #include "vamp-hostsdk/PluginHostAdapter.h" | 17 #include "vamp-hostsdk/PluginHostAdapter.h" |
25 #include "vamp-hostsdk/PluginChannelAdapter.h" | 18 #include "vamp-hostsdk/PluginChannelAdapter.h" |
26 #include "vamp-hostsdk/PluginInputDomainAdapter.h" | 19 #include "vamp-hostsdk/PluginInputDomainAdapter.h" |
27 #include "vamp-hostsdk/PluginLoader.h" | 20 #include "vamp-hostsdk/PluginLoader.h" |
28 //#include "vamp/vamp.h" | 21 |
22 #include "PyTypeConversions.h" | |
23 #include "PyRealTime.h" | |
29 | 24 |
30 #include <iostream> | 25 #include <iostream> |
31 #include <fstream> | 26 #include <fstream> |
32 #include <set> | 27 #include <set> |
33 #include <sndfile.h> | 28 #include <sndfile.h> |
34 | 29 |
35 #include <cstring> | 30 #include <cstring> |
36 #include <cstdlib> | 31 #include <cstdlib> |
37 #include <string> | 32 #include <string> |
38 | 33 |
39 #include "system.h" | |
40 | |
41 #include <cmath> | 34 #include <cmath> |
42 | |
43 | 35 |
44 using namespace std; | 36 using namespace std; |
45 using namespace Vamp; | 37 using namespace Vamp; |
46 | 38 |
47 using Vamp::Plugin; | 39 using Vamp::Plugin; |
49 using Vamp::RealTime; | 41 using Vamp::RealTime; |
50 using Vamp::HostExt::PluginLoader; | 42 using Vamp::HostExt::PluginLoader; |
51 | 43 |
52 #define HOST_VERSION "1.1" | 44 #define HOST_VERSION "1.1" |
53 | 45 |
46 // structure for holding plugin instance data | |
47 struct PyPluginData | |
48 { | |
49 PyPluginData(string k, Plugin *p, float rate) : | |
50 key(k), | |
51 plugin(p), | |
52 inputSampleRate(rate), | |
53 isInitialised(false), | |
54 channels(0), | |
55 blockSize(0), | |
56 stepSize(0) { | |
57 } | |
58 | |
59 string key; | |
60 Plugin *plugin; | |
61 float inputSampleRate; | |
62 bool isInitialised; | |
63 size_t channels; | |
64 size_t blockSize; | |
65 size_t stepSize; | |
66 Vamp::Plugin::FeatureSet output; | |
67 }; | |
54 | 68 |
55 /* MODULE HELPER FUNCTIONS */ | 69 /* MODULE HELPER FUNCTIONS */ |
56 PyDoc_STRVAR(xx_foo_doc, "Some description"); //!!! | 70 PyDoc_STRVAR(xx_foo_doc, "Some description"); //!!! |
57 | 71 |
58 /*obtain C plugin handle and key from pyCobject */ | 72 //!!! nb "The CObject API is deprecated" https://docs.python.org/2/c-api/cobject.html |
59 bool getPluginHandle | 73 |
60 (PyObject *pyPluginHandle, Plugin **plugin, string **pKey=NULL) { | 74 PyPluginData * |
61 | 75 getPluginData(PyObject *pyPluginHandle) |
62 //char errormsg[]="Wrong input argument: Plugin Handle required."; | 76 { |
63 | 77 PyPluginData *pd = 0; |
64 *plugin = NULL; | 78 if (PyCObject_Check(pyPluginHandle)) { |
65 if (!PyCObject_Check(pyPluginHandle)) return false; | 79 pd = (PyPluginData *)PyCObject_AsVoidPtr(pyPluginHandle); |
66 | 80 } |
67 //try to convert to Plugin pointer | 81 if (!pd || !pd->plugin) { |
68 Plugin *p = (Plugin*) PyCObject_AsVoidPtr(pyPluginHandle); | 82 PyErr_SetString(PyExc_AttributeError, |
69 if (!p) return false; | 83 "Invalid or already deleted plugin handle."); |
70 | 84 return 0; |
71 string pId; | |
72 | |
73 if (pKey) { | |
74 *pKey = (string*) PyCObject_GetDesc(pyPluginHandle); | |
75 if (!*pKey) return false; | |
76 pId = *(string*) *pKey; | |
77 | |
78 } else { | 85 } else { |
79 | 86 return pd; |
80 void *pKey = PyCObject_GetDesc(pyPluginHandle); | 87 } |
81 if (!pKey) return false; | 88 } |
82 pId = *(string*) pKey; | |
83 } | |
84 | |
85 string::size_type pos = pId.find(':'); | |
86 if (pos == string::npos) return false; | |
87 | |
88 pId = pId.substr(pId.rfind(':')+1); | |
89 string identifier = p->getIdentifier(); | |
90 | |
91 if (pId.compare(identifier)) return false; | |
92 | |
93 *plugin = p; | |
94 return true; | |
95 } | |
96 | |
97 /* | |
98 ---------------------------------------------------------------- | |
99 */ | |
100 | |
101 | |
102 | |
103 /* | |
104 VAMPYHOST MAIN | |
105 --------------------------------------------------------------------- | |
106 */ | |
107 | 89 |
108 static PyObject * | 90 static PyObject * |
109 vampyhost_enumeratePlugins(PyObject *self, PyObject *args) | 91 vampyhost_enumeratePlugins(PyObject *self, PyObject *args) |
110 { | 92 { |
111 PluginLoader *loader = PluginLoader::getInstance(); | 93 PluginLoader *loader = PluginLoader::getInstance(); |
144 PyObject *pyPluginKey; | 126 PyObject *pyPluginKey; |
145 | 127 |
146 if (!PyArg_ParseTuple(args, "S", &pyPluginKey)) { | 128 if (!PyArg_ParseTuple(args, "S", &pyPluginKey)) { |
147 PyErr_SetString(PyExc_TypeError, | 129 PyErr_SetString(PyExc_TypeError, |
148 "getLibraryPathForPlugin() takes plugin key (string) argument"); | 130 "getLibraryPathForPlugin() takes plugin key (string) argument"); |
149 return NULL; } | 131 return 0; } |
150 | 132 |
151 string pluginKey = toPluginKey(pyPluginKey); | 133 string pluginKey = toPluginKey(pyPluginKey); |
152 if (pluginKey == "") return NULL; | 134 if (pluginKey == "") return 0; |
153 | 135 |
154 PluginLoader *loader = PluginLoader::getInstance(); | 136 PluginLoader *loader = PluginLoader::getInstance(); |
155 string path = loader->getLibraryPathForPlugin(pluginKey); | 137 string path = loader->getLibraryPathForPlugin(pluginKey); |
156 PyObject *pyPath = PyString_FromString(path.c_str()); | 138 PyObject *pyPath = PyString_FromString(path.c_str()); |
157 return pyPath; | 139 return pyPath; |
163 PyObject *pyPluginKey; | 145 PyObject *pyPluginKey; |
164 | 146 |
165 if (!PyArg_ParseTuple(args, "S", &pyPluginKey)) { | 147 if (!PyArg_ParseTuple(args, "S", &pyPluginKey)) { |
166 PyErr_SetString(PyExc_TypeError, | 148 PyErr_SetString(PyExc_TypeError, |
167 "getPluginCategory() takes plugin key (string) argument"); | 149 "getPluginCategory() takes plugin key (string) argument"); |
168 return NULL; } | 150 return 0; } |
169 | 151 |
170 string pluginKey = toPluginKey(pyPluginKey); | 152 string pluginKey = toPluginKey(pyPluginKey); |
171 if (pluginKey == "") return NULL; | 153 if (pluginKey == "") return 0; |
172 | 154 |
173 PluginLoader *loader = PluginLoader::getInstance(); | 155 PluginLoader *loader = PluginLoader::getInstance(); |
174 PluginLoader::PluginCategoryHierarchy | 156 PluginLoader::PluginCategoryHierarchy |
175 category = loader->getPluginCategory(pluginKey); | 157 category = loader->getPluginCategory(pluginKey); |
176 | 158 |
179 } | 161 } |
180 | 162 |
181 static PyObject * | 163 static PyObject * |
182 vampyhost_getOutputList(PyObject *self, PyObject *args) | 164 vampyhost_getOutputList(PyObject *self, PyObject *args) |
183 { | 165 { |
184 PyObject *pyPluginHandle; | 166 PyObject *keyOrHandle; |
185 Plugin::OutputList outputs; | 167 Plugin::OutputList outputs; |
186 | 168 |
187 if (!PyArg_ParseTuple(args, "O", &pyPluginHandle)) { | 169 if (!PyArg_ParseTuple(args, "O", &keyOrHandle)) { |
188 PyErr_SetString(PyExc_TypeError, | 170 PyErr_SetString(PyExc_TypeError, |
189 "getOutputList() takes plugin handle (object) or plugin key (string) argument"); | 171 "getOutputList() takes plugin handle (object) or plugin key (string) argument"); |
190 return NULL; | 172 return 0; |
191 } | 173 } |
192 | 174 |
193 if (PyString_Check(pyPluginHandle) ) { | 175 if (PyString_Check(keyOrHandle) ) { |
194 | 176 |
195 // we have a plugin key | 177 // we have a plugin key |
196 | 178 |
197 string pluginKey = toPluginKey(pyPluginHandle); | 179 string pluginKey = toPluginKey(keyOrHandle); |
198 if (pluginKey == "") return NULL; | 180 if (pluginKey == "") return 0; |
199 | 181 |
200 PluginLoader *loader = PluginLoader::getInstance(); | 182 PluginLoader *loader = PluginLoader::getInstance(); |
201 | 183 |
202 Plugin *plugin = loader->loadPlugin | 184 Plugin *plugin = loader->loadPlugin |
203 (pluginKey, 48000, PluginLoader::ADAPT_ALL_SAFE); | 185 (pluginKey, 48000, PluginLoader::ADAPT_ALL_SAFE); |
204 if (!plugin) { | 186 if (!plugin) { |
205 string pyerr("Failed to load plugin: "); pyerr += pluginKey; | 187 string pyerr("Failed to load plugin: "); pyerr += pluginKey; |
206 PyErr_SetString(PyExc_TypeError,pyerr.c_str()); | 188 PyErr_SetString(PyExc_TypeError,pyerr.c_str()); |
207 return NULL; | 189 return 0; |
208 } | 190 } |
209 | 191 |
210 outputs = plugin->getOutputDescriptors(); | 192 outputs = plugin->getOutputDescriptors(); |
211 | 193 |
212 delete plugin; | 194 delete plugin; |
213 | 195 |
214 } else { | 196 } else { |
215 | 197 |
216 // we have a loaded plugin handle | 198 // we have a loaded plugin handle |
217 | 199 |
218 string *key; | 200 PyPluginData *pd = getPluginData(keyOrHandle); |
219 Plugin *plugin; | 201 if (!pd) return 0; |
220 | 202 |
221 if ( !getPluginHandle(pyPluginHandle, &plugin, &key) ) { | 203 outputs = pd->plugin->getOutputDescriptors(); |
222 PyErr_SetString(PyExc_TypeError, | |
223 "Invalid or deleted plugin handle."); | |
224 return NULL; } | |
225 | |
226 outputs = plugin->getOutputDescriptors(); | |
227 } | 204 } |
228 | 205 |
229 PyObject *pyList = PyList_New(outputs.size()); | 206 PyObject *pyList = PyList_New(outputs.size()); |
230 | 207 |
231 for (size_t i = 0; i < outputs.size(); ++i) { | 208 for (size_t i = 0; i < outputs.size(); ++i) { |
246 if (!PyArg_ParseTuple(args, "Sf", | 223 if (!PyArg_ParseTuple(args, "Sf", |
247 &pyPluginKey, | 224 &pyPluginKey, |
248 &inputSampleRate)) { | 225 &inputSampleRate)) { |
249 PyErr_SetString(PyExc_TypeError, | 226 PyErr_SetString(PyExc_TypeError, |
250 "loadPlugin() takes plugin key (string) and sample rate (number) arguments"); | 227 "loadPlugin() takes plugin key (string) and sample rate (number) arguments"); |
251 return NULL; } | 228 return 0; } |
252 | 229 |
253 string pluginKey = toPluginKey(pyPluginKey); | 230 string pluginKey = toPluginKey(pyPluginKey); |
254 if (pluginKey == "") return NULL; | 231 if (pluginKey == "") return 0; |
255 | 232 |
256 PluginLoader *loader = PluginLoader::getInstance(); | 233 PluginLoader *loader = PluginLoader::getInstance(); |
257 | 234 |
258 Plugin *plugin = loader->loadPlugin(pluginKey, inputSampleRate, | 235 Plugin *plugin = loader->loadPlugin(pluginKey, inputSampleRate, |
259 PluginLoader::ADAPT_ALL_SAFE); | 236 PluginLoader::ADAPT_ALL_SAFE); |
260 if (!plugin) { | 237 if (!plugin) { |
261 string pyerr("Failed to load plugin: "); pyerr += pluginKey; | 238 string pyerr("Failed to load plugin: "); pyerr += pluginKey; |
262 PyErr_SetString(PyExc_TypeError,pyerr.c_str()); | 239 PyErr_SetString(PyExc_TypeError,pyerr.c_str()); |
263 return NULL; | 240 return 0; |
264 } | 241 } |
265 | 242 |
266 PyPluginDescriptor *pd = new PyPluginDescriptor; | 243 PyPluginData *pd = new PyPluginData(pluginKey, plugin, inputSampleRate); |
267 | 244 return PyCObject_FromVoidPtr(pd, 0); |
268 pd->key = pluginKey; | 245 } |
269 pd->isInitialised = false; | |
270 pd->inputSampleRate = inputSampleRate; | |
271 | |
272 PyObject *pyPluginHandle = PyCObject_FromVoidPtrAndDesc( | |
273 (void*) plugin, (void*) pd, NULL); | |
274 | |
275 return pyPluginHandle; | |
276 } | |
277 | |
278 | |
279 | |
280 /* UNLOAD PLUGIN */ | |
281 | 246 |
282 static PyObject * | 247 static PyObject * |
283 vampyhost_unloadPlugin(PyObject *self, PyObject *args) | 248 vampyhost_unloadPlugin(PyObject *self, PyObject *args) |
284 { | 249 { |
285 PyObject *pyPluginHandle; | 250 PyObject *pyPluginHandle; |
286 | 251 |
287 if (!PyArg_ParseTuple(args, "O", &pyPluginHandle)) { | 252 if (!PyArg_ParseTuple(args, "O", &pyPluginHandle)) { |
288 PyErr_SetString(PyExc_TypeError, | 253 PyErr_SetString(PyExc_TypeError, |
289 "Wrong input argument: Plugin Handle required."); | 254 "unloadPlugin() takes plugin handle (object) argument"); |
290 return NULL; } | 255 return 0; |
291 | 256 } |
292 string *key; | 257 |
293 Plugin *plugin; | 258 PyPluginData *pd = getPluginData(pyPluginHandle); |
294 | 259 if (!pd) return 0; |
295 if ( !getPluginHandle(pyPluginHandle, &plugin, &key) ) { | 260 |
296 PyErr_SetString(PyExc_TypeError, | 261 /* Prevent repeated calls from causing segfault since it will fail |
297 "Invalid or already deleted plugin handle."); | 262 * type checking the 2nd time: */ |
298 return NULL; } | 263 PyCObject_SetVoidPtr(pyPluginHandle, 0); |
299 | 264 |
300 /* Prevent repeated calls from causing segfault | 265 delete pd->plugin; |
301 sice it will fail type checking the 2nd time: */ | |
302 PyCObject_SetVoidPtr(pyPluginHandle,NULL); | |
303 | |
304 PyPluginDescriptor *pd = (PyPluginDescriptor*) key; | |
305 | |
306 delete plugin; | |
307 delete pd; | 266 delete pd; |
308 return pyPluginHandle; | 267 return pyPluginHandle; |
309 | |
310 } | 268 } |
311 | 269 |
312 | 270 |
313 /* INITIALISE PLUGIN */ | 271 /* INITIALISE PLUGIN */ |
314 | 272 |
323 (size_t) &stepSize, | 281 (size_t) &stepSize, |
324 (size_t) &blockSize)) | 282 (size_t) &blockSize)) |
325 { | 283 { |
326 PyErr_SetString(PyExc_TypeError, | 284 PyErr_SetString(PyExc_TypeError, |
327 "Wrong input arguments: requires a valid plugin handle,channels,stepSize,blockSize."); | 285 "Wrong input arguments: requires a valid plugin handle,channels,stepSize,blockSize."); |
328 return NULL; | 286 return 0; |
329 } | 287 } |
330 | 288 |
331 Plugin *plugin; | 289 PyPluginData *pd = getPluginData(pyPluginHandle); |
332 string *key; | 290 if (!pd) return 0; |
333 | 291 |
334 if ( !getPluginHandle(pyPluginHandle, &plugin, &key) ) { | 292 pd->channels = channels; |
335 PyErr_SetString(PyExc_TypeError, | 293 pd->stepSize = stepSize; |
336 "Invalid plugin handle."); | 294 pd->blockSize = blockSize; |
337 return NULL; } | 295 |
338 | 296 if (!pd->plugin->initialise(channels, stepSize, blockSize)) { |
339 // here we cast the void pointer as PyPluginDescriptor instead of string | |
340 PyPluginDescriptor *plugDesc = (PyPluginDescriptor*) key; | |
341 | |
342 plugDesc->channels = channels; | |
343 plugDesc->stepSize = stepSize; | |
344 plugDesc->blockSize = blockSize; | |
345 | |
346 if (!plugin->initialise(channels, stepSize, blockSize)) { | |
347 std::cerr << "Failed to initialise native plugin adapter with channels = " << channels << ", stepSize = " << stepSize << ", blockSize = " << blockSize << " and ADAPT_ALL_SAFE set" << std::endl; | 297 std::cerr << "Failed to initialise native plugin adapter with channels = " << channels << ", stepSize = " << stepSize << ", blockSize = " << blockSize << " and ADAPT_ALL_SAFE set" << std::endl; |
348 PyErr_SetString(PyExc_TypeError, | 298 PyErr_SetString(PyExc_TypeError, |
349 "Plugin initialization failed."); | 299 "Plugin initialization failed."); |
350 return NULL; | 300 return 0; |
351 } | 301 } |
352 | 302 |
353 plugDesc->identifier = | 303 pd->isInitialised = true; |
354 plugDesc->key.substr(plugDesc->key.rfind(':')+1); | |
355 plugDesc->isInitialised = true; | |
356 | 304 |
357 return Py_True; | 305 return Py_True; |
358 } | 306 } |
359 | 307 |
360 /* RUN PROCESS */ | 308 /* RUN PROCESS */ |
370 &pyPluginHandle, // C object holding a pointer to a plugin and its descriptor | 318 &pyPluginHandle, // C object holding a pointer to a plugin and its descriptor |
371 &pyBuffer, // Audio data | 319 &pyBuffer, // Audio data |
372 &pyRealTime)) { // TimeStamp | 320 &pyRealTime)) { // TimeStamp |
373 PyErr_SetString(PyExc_TypeError, | 321 PyErr_SetString(PyExc_TypeError, |
374 "Required: plugin handle, buffer, timestmap."); | 322 "Required: plugin handle, buffer, timestmap."); |
375 return NULL; } | 323 return 0; } |
376 | 324 |
377 if (!PyRealTime_Check(pyRealTime)) { | 325 if (!PyRealTime_Check(pyRealTime)) { |
378 PyErr_SetString(PyExc_TypeError,"Valid timestamp required."); | 326 PyErr_SetString(PyExc_TypeError,"Valid timestamp required."); |
379 return NULL; } | 327 return 0; } |
380 | 328 |
381 string *key; | 329 PyPluginData *pd = getPluginData(pyPluginHandle); |
382 Plugin *plugin; | 330 if (!pd) return 0; |
383 | |
384 if (!getPluginHandle(pyPluginHandle, &plugin, &key)) { | |
385 PyErr_SetString(PyExc_AttributeError, | |
386 "Invalid or already deleted plugin handle."); | |
387 return NULL; | |
388 } | |
389 | |
390 PyPluginDescriptor *pd = (PyPluginDescriptor*) key; | |
391 | 331 |
392 if (!pd->isInitialised) { | 332 if (!pd->isInitialised) { |
393 PyErr_SetString(PyExc_StandardError, | 333 PyErr_SetString(PyExc_StandardError, |
394 "Plugin has not been initialised."); | 334 "Plugin has not been initialised."); |
395 return NULL; } | 335 return 0; |
336 } | |
396 | 337 |
397 int channels = pd->channels; | 338 int channels = pd->channels; |
398 // int blockSize = pd->blockSize; | 339 // int blockSize = pd->blockSize; |
399 | 340 |
400 if (!PyList_Check(pyBuffer)) { | 341 if (!PyList_Check(pyBuffer)) { |
401 PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input."); | 342 PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input."); |
402 return NULL; | 343 return 0; |
403 } | 344 } |
404 | 345 |
405 if (PyList_GET_SIZE(pyBuffer) != channels) { | 346 if (PyList_GET_SIZE(pyBuffer) != channels) { |
406 std::cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << std::endl; | 347 std::cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << std::endl; |
407 PyErr_SetString(PyExc_TypeError, "Wrong number of channels"); | 348 PyErr_SetString(PyExc_TypeError, "Wrong number of channels"); |
408 return NULL; | 349 return 0; |
409 } | 350 } |
410 | 351 |
411 float **inbuf = new float *[channels]; | 352 float **inbuf = new float *[channels]; |
412 | 353 |
413 PyTypeConversions typeConv; | 354 PyTypeConversions typeConv; |
424 } | 365 } |
425 | 366 |
426 RealTime timeStamp = *PyRealTime_AsRealTime(pyRealTime); | 367 RealTime timeStamp = *PyRealTime_AsRealTime(pyRealTime); |
427 | 368 |
428 //Call process and store the output | 369 //Call process and store the output |
429 pd->output = plugin->process(inbuf, timeStamp); | 370 pd->output = pd->plugin->process(inbuf, timeStamp); |
430 | 371 |
431 /* TODO: DO SOMETHONG WITH THE FEATURE SET HERE */ | 372 /* TODO: DO SOMETHONG WITH THE FEATURE SET HERE */ |
432 /// convert to appropriate python objects, reuse types and conversion utilities from Vampy ... | 373 /// convert to appropriate python objects, reuse types and conversion utilities from Vampy ... |
433 | 374 |
434 delete[] inbuf; | 375 delete[] inbuf; |
435 | 376 |
436 return NULL; //!!! Need to return actual features! | 377 return 0; //!!! Need to return actual features! |
437 | 378 |
438 } | 379 } |
439 | 380 |
440 /* GET / SET OUTPUT */ | 381 /* GET / SET OUTPUT */ |
441 | 382 |
451 if (!PyArg_ParseTuple(args, "OO", | 392 if (!PyArg_ParseTuple(args, "OO", |
452 &pyPluginHandle, // C object holding a pointer to a plugin and its descriptor | 393 &pyPluginHandle, // C object holding a pointer to a plugin and its descriptor |
453 &pyOutput)) { // Output reference | 394 &pyOutput)) { // Output reference |
454 PyErr_SetString(PyExc_TypeError, | 395 PyErr_SetString(PyExc_TypeError, |
455 "Required: plugin handle, buffer, timestmap."); | 396 "Required: plugin handle, buffer, timestmap."); |
456 return NULL; } | 397 return 0; } |
457 | 398 |
458 string *key; | 399 PyPluginData *pd = getPluginData(pyPluginHandle); |
459 Plugin *plugin; | 400 if (!pd) return 0; |
460 | |
461 if ( !getPluginHandle(pyPluginHandle, &plugin, &key) ) { | |
462 PyErr_SetString(PyExc_AttributeError, | |
463 "Invalid or already deleted plugin handle."); | |
464 return NULL; } | |
465 | |
466 PyPluginDescriptor *pd = (PyPluginDescriptor*) key; | |
467 | 401 |
468 unsigned int outputNo = (unsigned int) PyInt_AS_LONG(pyOutput); | 402 unsigned int outputNo = (unsigned int) PyInt_AS_LONG(pyOutput); |
469 | 403 |
470 //Get output list: but we don't need it | 404 //Get output list: but we don't need it |
471 //Plugin::FeatureList features = pd->output[outputNo]; | 405 //Plugin::FeatureList features = pd->output[outputNo]; |
477 | 411 |
478 for (size_t i = 0; i < outLength; ++i) { | 412 for (size_t i = 0; i < outLength; ++i) { |
479 // Test: | 413 // Test: |
480 /* | 414 /* |
481 XxoObject *pyFeature = PyObject_New(XxoObject, &Xxo_Type); | 415 XxoObject *pyFeature = PyObject_New(XxoObject, &Xxo_Type); |
482 if (pyFeature == NULL) break; //return NULL; | 416 if (pyFeature == 0) break; //return 0; |
483 | 417 |
484 pyFeature->x_attr = NULL; | 418 pyFeature->x_attr = 0; |
485 pyFeature->feature = &pd->output[outputNo][i]; | 419 pyFeature->feature = &pd->output[outputNo][i]; |
486 | 420 |
487 PyList_SET_ITEM(pyFeatureList,i,(PyObject*)pyFeature); | 421 PyList_SET_ITEM(pyFeatureList,i,(PyObject*)pyFeature); |
488 */ | 422 */ |
489 } | 423 } |
502 // Plugin::OutputList outputs = plugin->getOutputDescriptors(); | 436 // Plugin::OutputList outputs = plugin->getOutputDescriptors(); |
503 // | 437 // |
504 // if (outputs.size()<1) { | 438 // if (outputs.size()<1) { |
505 // string pyerr("Plugin has no output: "); pyerr += pluginKey; | 439 // string pyerr("Plugin has no output: "); pyerr += pluginKey; |
506 // PyErr_SetString(PyExc_TypeError,pyerr.c_str()); | 440 // PyErr_SetString(PyExc_TypeError,pyerr.c_str()); |
507 // return NULL; | 441 // return 0; |
508 // } | 442 // } |
509 // | 443 // |
510 // //New list object | 444 // //New list object |
511 // PyObject *pyList = PyList_New(outputs.size()); | 445 // PyObject *pyList = PyList_New(outputs.size()); |
512 // | 446 // |
561 PyDoc_STR("frame2RealTime((int64)frame, (uint32)sampleRate ) -> returns new RealTime object from frame.")}, | 495 PyDoc_STR("frame2RealTime((int64)frame, (uint32)sampleRate ) -> returns new RealTime object from frame.")}, |
562 | 496 |
563 {"realtime", (PyCFunction)RealTime_new, METH_VARARGS, | 497 {"realtime", (PyCFunction)RealTime_new, METH_VARARGS, |
564 PyDoc_STR("realtime() -> returns new RealTime object")}, | 498 PyDoc_STR("realtime() -> returns new RealTime object")}, |
565 */ | 499 */ |
566 {NULL, NULL} /* sentinel */ | 500 {0, 0} /* sentinel */ |
567 }; | 501 }; |
568 | 502 |
569 //Documentation for our new module | 503 //Documentation for our new module |
570 PyDoc_STRVAR(module_doc, "This is a template module just for instruction."); | 504 PyDoc_STRVAR(module_doc, "This is a template module just for instruction."); |
571 | 505 |
587 return; | 521 return; |
588 // PyModule_AddObject(m, "Real_Time", (PyObject *)&RealTime_Type); | 522 // PyModule_AddObject(m, "Real_Time", (PyObject *)&RealTime_Type); |
589 | 523 |
590 /* Create the module and add the functions */ | 524 /* Create the module and add the functions */ |
591 m = Py_InitModule3("vampyhost", vampyhost_methods, module_doc); | 525 m = Py_InitModule3("vampyhost", vampyhost_methods, module_doc); |
592 if (m == NULL) return; | 526 if (!m) return; |
593 | 527 |
594 import_array(); | 528 import_array(); |
595 | 529 |
596 // PyModule_AddObject(m, "realtime", (PyObject *)&RealTime_Type); | 530 // PyModule_AddObject(m, "realtime", (PyObject *)&RealTime_Type); |
597 | 531 |