comparison PyPlugin.cpp @ 72:ffaa1fb3d7de vampyhost

inline is not a useful keyword with contemporary compilers
author Chris Cannam
date Mon, 24 Nov 2014 09:50:49 +0000
parents 40a01bb24209
children
comparison
equal deleted inserted replaced
71:40a01bb24209 72:ffaa1fb3d7de
473 // this would disable all outputs even if some are valid 473 // this would disable all outputs even if some are valid
474 // if (process) m_processFailure = true; 474 // if (process) m_processFailure = true;
475 475
476 } 476 }
477 477
478 /// optimised process call
479 PyPlugin::FeatureSet
480 PyPlugin::processMethodCall(const float *const *inputBuffers,Vamp::RealTime timestamp)
481 {
482
483 /// Optimizations: 1) we avoid ...ObjArg functions since we know
484 /// the number of arguments, and we don't like va_list parsing
485 /// in the process. 2) Also: we're supposed to incref args,
486 /// but instead, we let the arguments tuple steal the references
487 /// and decref them when it is deallocated.
488 /// 3) all conversions are now using the fast sequence protocol
489 /// (indexing the underlying object array).
490
491 FeatureSet rFeatureSet;
492 PyObject *pyChannelList = NULL;
493
494 if (m_processType == numpy_bufferProcess) {
495 pyChannelList = m_ti.InputBuffers_As_SharedMemoryList(
496 inputBuffers,m_channels,m_blockSize,m_inputDomain);
497 }
498
499 if (m_processType == legacyProcess) {
500 pyChannelList = m_ti.InputBuffers_As_PythonLists(
501 inputBuffers,m_channels,m_blockSize,m_inputDomain);
502 }
503
504 #ifdef HAVE_NUMPY
505 if (m_processType == numpy_arrayProcess) {
506 pyChannelList = m_ti.InputBuffers_As_NumpyArray(
507 inputBuffers,m_channels,m_blockSize,m_inputDomain);
508 }
509 #endif
510
511 /// we don't expect these to fail unless out of memory (which is very unlikely on modern systems)
512 #ifdef _DEBUG
513 if (!pyChannelList) {
514 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
515 std::string method = PyString_AsString(m_pyProcess);
516 cerr << PLUGIN_ERROR << "Failed to create channel list." << endl;
517 return rFeatureSet;
518 }
519 #endif
520
521 PyObject *pyTimeStamp = NULL;
522
523 if (m_useRealTimeFlag) {
524 //(1) pass TimeStamp as PyRealTime object
525 pyTimeStamp = PyRealTime_FromRealTime(timestamp);
526
527 } else {
528 //(2) pass TimeStamp as frame count (long Sample Count)
529 pyTimeStamp = PyLong_FromLong(Vamp::RealTime::realTime2Frame
530 (timestamp, (unsigned int) m_inputSampleRate));
531 }
532
533
534 #ifdef _DEBUG
535 if (!pyTimeStamp) {
536 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
537 std::string method = PyString_AsString(m_pyProcess);
538 cerr << PLUGIN_ERROR << "Failed to create RealTime time stamp." << endl;
539 Py_DECREF(pyChannelList);
540 return rFeatureSet;
541 }
542 #endif
543
544 /// Old method: Call python process (returns new reference)
545 /// PyObject *pyValue = PyObject_CallMethodObjArgs
546 /// (m_pyInstance,m_pyProcess,pyChannelList,pyTimeStamp,NULL);
547
548 PyObject *pyArgs = PyTuple_New(2);
549 PyTuple_SET_ITEM(pyArgs, 0, pyChannelList);
550 PyTuple_SET_ITEM(pyArgs, 1, pyTimeStamp);
551
552 /// Call python process (returns new reference) {kwArgs = NULL}
553 PyObject *pyValue = PyObject_Call(m_pyProcessCallable,pyArgs,NULL);
554
555 if (!pyValue) {
556 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
557 std::string method = PyString_AsString(m_pyProcess);
558 cerr << PLUGIN_ERROR << "An error occurred while evaluating Python process." << endl;
559 Py_CLEAR(pyValue);
560 Py_CLEAR(pyArgs);
561 return rFeatureSet;
562 }
563
564 rFeatureSet = m_ti.PyValue_To_FeatureSet(pyValue);
565 if (!m_ti.error) {
566 Py_DECREF(pyValue);
567 Py_DECREF(pyArgs);
568 } else {
569 typeErrorHandler(PyString_AsString(m_pyProcess),true);
570 Py_CLEAR(pyValue);
571 Py_CLEAR(pyArgs);
572 }
573 return rFeatureSet;
574 }