Mercurial > hg > vampy-host
comparison vampyhost.cpp @ 12:d0d91312e5a2
Prepare attempt to build using VamPy structures
author | Chris Cannam |
---|---|
date | Thu, 20 Nov 2014 13:03:50 +0000 |
parents | d29c25695f5e |
children | 8565ec421f9c |
comparison
equal
deleted
inserted
replaced
7:d29c25695f5e | 12:d0d91312e5a2 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ |
2 | 2 |
3 //include for python extension module: must be first | 3 //include for python extension module: must be first |
4 #include <Python.h> | 4 #include <Python.h> |
5 #include <vampyhost.h> | 5 #include <vampyhost.h> |
6 #include <pyRealTime.h> | 6 |
7 #include <PyRealTime.h> | |
7 | 8 |
8 //!!! NB all our NumPy stuff is currently using the deprecated API -- | 9 //!!! NB all our NumPy stuff is currently using the deprecated API -- |
9 //!!! need to work out how to update this | 10 //!!! need to work out how to update this |
10 #include "numpy/arrayobject.h" | 11 //#include "numpy/arrayobject.h" |
12 | |
13 #define HAVE_NUMPY 1 // Required | |
14 | |
15 #include "PyTypeConversions.h" | |
11 | 16 |
12 //includes for vamp host | 17 //includes for vamp host |
13 #include "vamp-hostsdk/Plugin.h" | 18 #include "vamp-hostsdk/Plugin.h" |
14 #include "vamp-hostsdk/PluginHostAdapter.h" | 19 #include "vamp-hostsdk/PluginHostAdapter.h" |
15 #include "vamp-hostsdk/PluginChannelAdapter.h" | 20 #include "vamp-hostsdk/PluginChannelAdapter.h" |
410 plugDesc->isInitialised = true; | 415 plugDesc->isInitialised = true; |
411 | 416 |
412 return Py_True; | 417 return Py_True; |
413 } | 418 } |
414 | 419 |
415 // These conversion functions are borrowed from PyTypeInterface in VamPy | |
416 | |
417 template<typename RET, typename DTYPE> | |
418 static | |
419 RET *pyArrayConvert(char* raw_data_ptr, long length, size_t strides) | |
420 { | |
421 RET *rValue = new RET[length]; | |
422 | |
423 /// check if the array is continuous, if not use strides info | |
424 if (sizeof(DTYPE)!=strides) { | |
425 char* data = (char*) raw_data_ptr; | |
426 for (long i = 0; i<length; ++i){ | |
427 rValue[i] = (RET)(*((DTYPE*)data)); | |
428 data += strides; | |
429 } | |
430 return rValue; | |
431 } | |
432 | |
433 DTYPE* data = (DTYPE*) raw_data_ptr; | |
434 for (long i = 0; i<length; ++i){ | |
435 rValue[i] = (RET)data[i]; | |
436 } | |
437 | |
438 return rValue; | |
439 } | |
440 | |
441 static float * | |
442 pyArrayToFloatArray(PyObject *pyValue) | |
443 { | |
444 if (!PyArray_Check(pyValue)) { | |
445 cerr << "pyArrayToFloatArray: Failed, object has no array interface" << endl; | |
446 return 0; | |
447 } | |
448 | |
449 PyArrayObject* pyArray = (PyArrayObject*) pyValue; | |
450 PyArray_Descr* descr = pyArray->descr; | |
451 | |
452 /// check raw data and descriptor pointers | |
453 if (pyArray->data == 0 || descr == 0) { | |
454 cerr << "pyArrayToFloatArray: Failed, NumPy array has NULL data or descriptor" << endl; | |
455 return 0; | |
456 } | |
457 | |
458 /// check dimensions | |
459 if (pyArray->nd != 1) { | |
460 cerr << "pyArrayToFloatArray: Failed, NumPy array is multi-dimensional" << endl; | |
461 return 0; | |
462 } | |
463 | |
464 /// check strides (useful if array is not continuous) | |
465 size_t strides = *((size_t*) pyArray->strides); | |
466 | |
467 /// convert the array | |
468 switch (descr->type_num) { | |
469 case NPY_FLOAT : // dtype='float32' | |
470 return pyArrayConvert<float,float>(pyArray->data,pyArray->dimensions[0],strides); | |
471 case NPY_DOUBLE : // dtype='float64' | |
472 return pyArrayConvert<float,double>(pyArray->data,pyArray->dimensions[0],strides); | |
473 default: | |
474 cerr << "pyArrayToFloatArray: Failed: Unsupported value type " << descr->type_num << " in NumPy array object (only float32, float64 supported)" << endl; | |
475 return 0; | |
476 } | |
477 } | |
478 | |
479 | |
480 /* RUN PROCESS */ | 420 /* RUN PROCESS */ |
481 | 421 |
482 static PyObject * | 422 static PyObject * |
483 vampyhost_process(PyObject *self, PyObject *args) | 423 vampyhost_process(PyObject *self, PyObject *args) |
484 { | 424 { |
512 if (!pd->isInitialised) { | 452 if (!pd->isInitialised) { |
513 PyErr_SetString(PyExc_StandardError, | 453 PyErr_SetString(PyExc_StandardError, |
514 "Plugin has not been initialised."); | 454 "Plugin has not been initialised."); |
515 return NULL; } | 455 return NULL; } |
516 | 456 |
517 size_t channels = pd->channels; | 457 int channels = pd->channels; |
518 size_t blockSize = pd->blockSize; | 458 // int blockSize = pd->blockSize; |
519 | 459 |
520 if (!PyList_Check(pyBuffer)) { | 460 if (!PyList_Check(pyBuffer)) { |
521 PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input."); | 461 PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input."); |
522 return NULL; | 462 return NULL; |
523 } | 463 } |
528 return NULL; | 468 return NULL; |
529 } | 469 } |
530 | 470 |
531 float **inbuf = new float *[channels]; | 471 float **inbuf = new float *[channels]; |
532 | 472 |
473 PyTypeConversions typeConv; | |
474 typeConv.setNumpyInstalled(true); | |
475 | |
476 vector<vector<float> > data; | |
533 for (int c = 0; c < channels; ++c) { | 477 for (int c = 0; c < channels; ++c) { |
534 PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c); | 478 PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c); |
535 inbuf[c] = pyArrayToFloatArray(cbuf); | 479 data.push_back(typeConv.PyArray_To_FloatVector(cbuf)); |
536 if (!inbuf[c]) { | 480 } |
537 PyErr_SetString(PyExc_TypeError,"NumPy Array required for each channel in process input."); | 481 |
538 return NULL; | 482 for (int c = 0; c < channels; ++c) { |
539 } | 483 inbuf[c] = &data[c][0]; |
540 } | 484 } |
541 | 485 |
542 RealTime timeStamp = *PyRealTime_AsPointer(pyRealTime); | 486 RealTime timeStamp = *PyRealTime_AsRealTime(pyRealTime); |
543 | 487 |
544 //Call process and store the output | 488 //Call process and store the output |
545 pd->output = plugin->process(inbuf, timeStamp); | 489 pd->output = plugin->process(inbuf, timeStamp); |
546 | 490 |
547 /* TODO: DO SOMETHONG WITH THE FEATURE SET HERE */ | 491 /* TODO: DO SOMETHONG WITH THE FEATURE SET HERE */ |
548 /// convert to appropriate python objects, reuse types and conversion utilities from Vampy ... | 492 /// convert to appropriate python objects, reuse types and conversion utilities from Vampy ... |
549 | 493 |
550 | |
551 for (int c = 0; c < channels; ++c){ | |
552 delete[] inbuf[c]; | |
553 } | |
554 delete[] inbuf; | 494 delete[] inbuf; |
555 | 495 |
556 return NULL; //!!! Need to return actual features! | 496 return NULL; //!!! Need to return actual features! |
557 | 497 |
558 } | 498 } |
671 | 611 |
672 {"getOutput", vampyhost_getOutput, METH_VARARGS, | 612 {"getOutput", vampyhost_getOutput, METH_VARARGS, |
673 xx_foo_doc}, | 613 xx_foo_doc}, |
674 | 614 |
675 /* Add RealTime Module Methods */ | 615 /* Add RealTime Module Methods */ |
676 | 616 /* |
677 {"frame2RealTime", (PyCFunction)RealTime_frame2RealTime, METH_VARARGS, | 617 {"frame2RealTime", (PyCFunction)RealTime_frame2RealTime, METH_VARARGS, |
678 PyDoc_STR("frame2RealTime((int64)frame, (uint32)sampleRate ) -> returns new RealTime object from frame.")}, | 618 PyDoc_STR("frame2RealTime((int64)frame, (uint32)sampleRate ) -> returns new RealTime object from frame.")}, |
679 | 619 |
680 {"realtime", (PyCFunction)RealTime_new, METH_VARARGS, | 620 {"realtime", (PyCFunction)RealTime_new, METH_VARARGS, |
681 PyDoc_STR("realtime() -> returns new RealTime object")}, | 621 PyDoc_STR("realtime() -> returns new RealTime object")}, |
682 | 622 */ |
683 {NULL, NULL} /* sentinel */ | 623 {NULL, NULL} /* sentinel */ |
684 }; | 624 }; |
685 | 625 |
686 //Documentation for our new module | 626 //Documentation for our new module |
687 PyDoc_STRVAR(module_doc, "This is a template module just for instruction."); | 627 PyDoc_STRVAR(module_doc, "This is a template module just for instruction."); |