Mercurial > hg > vampy-host
comparison PyPluginObject.cpp @ 40:fa3f80d4e340
2D array conversion (incorrect, crashing)
author | Chris Cannam |
---|---|
date | Wed, 26 Nov 2014 15:58:46 +0000 |
parents | 13dcfe8c7ed7 |
children | 55fcd0e3e513 |
comparison
equal
deleted
inserted
replaced
39:13dcfe8c7ed7 | 40:fa3f80d4e340 |
---|---|
374 } | 374 } |
375 | 375 |
376 return pyFs; | 376 return pyFs; |
377 } | 377 } |
378 | 378 |
379 static vector<vector<float> > | |
380 convertPluginInput(PyObject *pyBuffer, int channels, int blockSize) | |
381 { | |
382 vector<vector<float> > data; | |
383 | |
384 VectorConversion conv; | |
385 | |
386 if (PyArray_CheckExact(pyBuffer)) { | |
387 | |
388 data = conv.Py2DArray_To_FloatVector(pyBuffer); | |
389 | |
390 if (conv.error) { | |
391 PyErr_SetString(PyExc_TypeError, conv.getError().str().c_str()); | |
392 return data; | |
393 } | |
394 | |
395 } else { | |
396 | |
397 if (!PyList_Check(pyBuffer)) { | |
398 PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input."); | |
399 return data; | |
400 } | |
401 | |
402 if (PyList_GET_SIZE(pyBuffer) != channels) { | |
403 cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << endl; | |
404 PyErr_SetString(PyExc_TypeError, "Wrong number of channels"); | |
405 return data; | |
406 } | |
407 | |
408 for (int c = 0; c < channels; ++c) { | |
409 PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c); | |
410 data.push_back(conv.PyValue_To_FloatVector(cbuf)); | |
411 } | |
412 | |
413 for (int c = 0; c < channels; ++c) { | |
414 if ((int)data[c].size() != blockSize) { | |
415 cerr << "Wrong number of samples on channel " << c << ": expected " << blockSize << " (plugin's block size), got " << data[c].size() << endl; | |
416 PyErr_SetString(PyExc_TypeError, "Wrong number of samples"); | |
417 return vector<vector<float> >(); | |
418 } | |
419 } | |
420 } | |
421 | |
422 return data; | |
423 } | |
424 | |
379 static PyObject * | 425 static PyObject * |
380 process(PyObject *self, PyObject *args) | 426 process(PyObject *self, PyObject *args) |
381 { | 427 { |
382 PyObject *pyBuffer; | 428 PyObject *pyBuffer; |
383 PyObject *pyRealTime; | 429 PyObject *pyRealTime; |
384 | 430 |
385 if (!PyArg_ParseTuple(args, "OO", | 431 if (!PyArg_ParseTuple(args, "OO", |
386 &pyBuffer, // Audio data | 432 &pyBuffer, // Audio data |
387 &pyRealTime)) { // TimeStamp | 433 &pyRealTime)) { // TimeStamp |
388 PyErr_SetString(PyExc_TypeError, | 434 PyErr_SetString(PyExc_TypeError, |
389 "process() takes plugin handle (object), buffer (2D array of channels * samples floats) and timestamp (RealTime) arguments"); | 435 "process() takes plugin handle (object), buffer (list of arrays of floats, one array per channel) and timestamp (RealTime) arguments"); |
390 return 0; } | 436 return 0; } |
391 | 437 |
392 if (!PyRealTime_Check(pyRealTime)) { | 438 if (!PyRealTime_Check(pyRealTime)) { |
393 PyErr_SetString(PyExc_TypeError,"Valid timestamp required."); | 439 PyErr_SetString(PyExc_TypeError, "Valid timestamp required."); |
394 return 0; } | 440 return 0; } |
395 | |
396 if (!PyList_Check(pyBuffer)) { | |
397 PyErr_SetString(PyExc_TypeError, "List of NumPy Array required for process input."); | |
398 return 0; | |
399 } | |
400 | 441 |
401 PyPluginObject *pd = getPluginObject(self); | 442 PyPluginObject *pd = getPluginObject(self); |
402 if (!pd) return 0; | 443 if (!pd) return 0; |
403 | 444 |
404 if (!pd->isInitialised) { | 445 if (!pd->isInitialised) { |
405 PyErr_SetString(PyExc_StandardError, | 446 PyErr_SetString(PyExc_StandardError, |
406 "Plugin has not been initialised."); | 447 "Plugin has not been initialised."); |
407 return 0; | 448 return 0; |
408 } | 449 } |
409 | 450 |
410 int channels = pd->channels; | 451 int channels = pd->channels; |
411 | 452 vector<vector<float> > data = |
412 if (PyList_GET_SIZE(pyBuffer) != channels) { | 453 convertPluginInput(pyBuffer, channels, pd->blockSize); |
413 cerr << "Wrong number of channels: got " << PyList_GET_SIZE(pyBuffer) << ", expected " << channels << endl; | 454 if (data.empty()) return 0; |
414 PyErr_SetString(PyExc_TypeError, "Wrong number of channels"); | |
415 return 0; | |
416 } | |
417 | 455 |
418 float **inbuf = new float *[channels]; | 456 float **inbuf = new float *[channels]; |
419 | |
420 VectorConversion typeConv; | |
421 | |
422 vector<vector<float> > data; | |
423 for (int c = 0; c < channels; ++c) { | 457 for (int c = 0; c < channels; ++c) { |
424 PyObject *cbuf = PyList_GET_ITEM(pyBuffer, c); | |
425 data.push_back(typeConv.PyValue_To_FloatVector(cbuf)); | |
426 } | |
427 | |
428 for (int c = 0; c < channels; ++c) { | |
429 if (data[c].size() != pd->blockSize) { | |
430 cerr << "Wrong number of samples on channel " << c << ": expected " << pd->blockSize << " (plugin's block size), got " << data[c].size() << endl; | |
431 PyErr_SetString(PyExc_TypeError, "Wrong number of samples"); | |
432 return 0; | |
433 } | |
434 inbuf[c] = &data[c][0]; | 458 inbuf[c] = &data[c][0]; |
435 } | 459 } |
436 | |
437 RealTime timeStamp = *PyRealTime_AsRealTime(pyRealTime); | 460 RealTime timeStamp = *PyRealTime_AsRealTime(pyRealTime); |
438 | |
439 Plugin::FeatureSet fs = pd->plugin->process(inbuf, timeStamp); | 461 Plugin::FeatureSet fs = pd->plugin->process(inbuf, timeStamp); |
440 | |
441 delete[] inbuf; | 462 delete[] inbuf; |
442 | 463 |
443 return convertFeatureSet(fs); | 464 return convertFeatureSet(fs); |
444 } | 465 } |
445 | 466 |
588 0, /*tp_str*/ | 609 0, /*tp_str*/ |
589 PyObject_GenericGetAttr, /*tp_getattro*/ | 610 PyObject_GenericGetAttr, /*tp_getattro*/ |
590 PyObject_GenericSetAttr, /*tp_setattro*/ | 611 PyObject_GenericSetAttr, /*tp_setattro*/ |
591 0, /*tp_as_buffer*/ | 612 0, /*tp_as_buffer*/ |
592 Py_TPFLAGS_DEFAULT, /*tp_flags*/ | 613 Py_TPFLAGS_DEFAULT, /*tp_flags*/ |
593 "Vamp plugin object.", /*tp_doc*/ | 614 "Plugin object, providing a low-level API for running a Vamp plugin.", /*tp_doc*/ |
594 0, /*tp_traverse*/ | 615 0, /*tp_traverse*/ |
595 0, /*tp_clear*/ | 616 0, /*tp_clear*/ |
596 0, /*tp_richcompare*/ | 617 0, /*tp_richcompare*/ |
597 0, /*tp_weaklistoffset*/ | 618 0, /*tp_weaklistoffset*/ |
598 0, /*tp_iter*/ | 619 0, /*tp_iter*/ |