Mercurial > hg > vampy
diff PyPlugin.cpp @ 51:c1e4f706ca9a
Fix numpy version incompatibility issues and updated some example plugins.
author | fazekasgy |
---|---|
date | Thu, 08 Oct 2009 08:47:28 +0000 |
parents | 27bab3a16c9a |
children | 5664fe298af2 |
line wrap: on
line diff
--- a/PyPlugin.cpp Tue Oct 06 12:37:01 2009 +0000 +++ b/PyPlugin.cpp Thu Oct 08 08:47:28 2009 +0000 @@ -30,7 +30,7 @@ Mutex PyPlugin::m_pythonInterpreterMutex; -PyPlugin::PyPlugin(std::string pluginKey, float inputSampleRate, PyObject *pyClass, int &instcount) : +PyPlugin::PyPlugin(std::string pluginKey, float inputSampleRate, PyObject *pyClass, int &instcount, bool &numpyInstalled) : Plugin(inputSampleRate), m_pyClass(pyClass), m_instcount(instcount), @@ -44,7 +44,9 @@ m_pyProcess(NULL), m_inputDomain(TimeDomain), m_quitOnErrorFlag(false), - m_debugFlag(false) + m_debugFlag(false), + m_numpyInstalled(numpyInstalled), + m_processFailure(false) { m_ti.setInputSampleRate(inputSampleRate); MutexLocker locker(&m_pythonInterpreterMutex); @@ -86,6 +88,7 @@ if (m_debugFlag && st_flag) cerr << "Strict type conversion ON for: " << m_class << endl; m_ti.setStrictTypingFlag(st_flag); + m_ti.setNumpyInstalled(m_numpyInstalled); } @@ -188,6 +191,7 @@ PyPlugin::reset() { MutexLocker locker(&m_pythonInterpreterMutex); + m_processFailure = false; genericMethodCall("reset"); } @@ -290,6 +294,8 @@ return FeatureSet(); } + if (m_processFailure) return FeatureSet(); + return processMethodCall(inputBuffers,timestamp); } @@ -298,6 +304,7 @@ PyPlugin::getRemainingFeatures() { MutexLocker locker(&m_pythonInterpreterMutex); + if (m_processFailure) return FeatureSet(); FeatureSet rValue; return genericMethodCall("getRemainingFeatures",rValue); } @@ -355,6 +362,7 @@ //quering process implementation type char legacyMethod[]="process"; char numpyMethod[]="processN"; + m_processFailure = false; if (PyObject_HasAttrString(m_pyInstance,legacyMethod) && m_processType == 0) @@ -384,33 +392,68 @@ if (m_vampyFlags & vf_ARRAY) { #ifdef HAVE_NUMPY - m_processType = numpy_arrayProcess; - if (m_debugFlag) cerr << "Process using numpy array interface." << endl; + if (m_numpyInstalled) { m_processType = numpy_arrayProcess; + if (m_debugFlag) + cerr << "Process using numpy array interface." << endl; + } + else { + m_processFailure = true; + char method[]="initialise::setProcessType"; + cerr << PLUGIN_ERROR + << "This plugin requests the Numpy array interface by setting " + << " the vf_ARRAY flag in its __init__() function." << endl + << "However, we could not found a version of Numpy compatible with this build of Vampy." << endl + << "If you have a numerical library installed that supports the buffer interface, " << endl + << "you can request this interface instead by setting the vf_BUFFER flag." << endl; + } #else - cerr << "Error: This version of vampy was compiled without numpy support, " - << "however the vf_ARRAY flag is set for plugin: " << m_class << endl - << "The default behaviour is: passing a python list of samples for each channel in process() " - << "or a list of memory buffers in processN(). " << endl - << "This can be used create numpy arrays using the numpy.frombuffer() command." << endl; + m_processFailure = true; + char method[]="initialise::setProcessType"; + cerr << PLUGIN_ERROR + << "Error: This version of vampy was compiled without numpy support, " + << "however the vf_ARRAY flag is set for plugin: " << m_class << endl + << "The default behaviour is: passing a python list of samples for each channel in process() " + << "or a list of memory buffers in processN(). " << endl + << "This can be used create numpy arrays using the numpy.frombuffer() command." << endl; #endif } - if (!m_processType) + if (!m_pyProcessCallable) { m_processType = not_implemented; m_pyProcess = NULL; - m_pyProcessCallable = NULL; char method[]="initialise::setProcessType"; cerr << PLUGIN_ERROR << " No process implementation found. Plugin will do nothing." << endl; + m_processFailure = true; } } void -PyPlugin::typeErrorHandler(char *method) const +PyPlugin::typeErrorHandler(char *method, bool process) const { bool strict = false; while (m_ti.error) { PyTypeInterface::ValueError e = m_ti.getError(); +#ifdef HAVE_NUMPY + // disable the process completely if numpy types are returned + // but a compatible version was not loaded. + // This is required because if an object is returned from + // the wrong build, malloc complains about its size + // (i.e. the interpreter doesn't free it properly) + // and the process may be leaking. + // Note: this only happens in the obscure situation when + // someone forces to return wrong numpy types from an + // incompatible version using the buffer interface. + // In this case the incampatible library is still usable, + // but manual conversion to python builtins is required. + // If the ARRAY interface is set but Numpy is not installed + // the process will be disabled already at initialisation. + if (process && !m_numpyInstalled && e.str().find("numpy")!=std::string::npos) + { + m_processFailure = true; + cerr << "Warning: incompatible numpy type encountered. Disabling process." << endl; + } +#endif cerr << PLUGIN_ERROR << e.str() << endl; if (e.strict) strict = true; // e.print(); @@ -422,5 +465,9 @@ /// It would be best if hosts could catch an exception instead /// and display something meaningful to the user. if (strict && m_quitOnErrorFlag) exit(EXIT_FAILURE); + + // this would disable all outputs even if some are valid + // if (process) m_processFailure = true; + }