comparison vampy-main.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 7e59caea821b
comparison
equal deleted inserted replaced
50:3868da185d73 51:c1e4f706ca9a
10 */ 10 */
11 11
12 #include <Python.h> 12 #include <Python.h>
13 13
14 #ifdef HAVE_NUMPY 14 #ifdef HAVE_NUMPY
15 #define PY_ARRAY_UNIQUE_SYMBOL VAMPY_ARRAY_API 15
16 // define a unique API pointer
17 #define PY_ARRAY_UNIQUE_SYMBOL VAMPY_ARRAY_API
16 #include "numpy/arrayobject.h" 18 #include "numpy/arrayobject.h"
19
20 // prevent building with very old versions of numpy
21 #ifndef NPY_VERSION
22 #undef HAVE_NUMPY
23 #endif
24
25 #endif
26
27 // this is not part of the API, but we will require it for a bug workaround
28 // define this symbol if you use another version of numpy in the makefile
29 // Vampy will not attempt to load a lower version than specified
30 #ifdef HAVE_NUMPY
31 #ifndef NUMPY_SHORTVERSION
32 #define NUMPY_SHORTVERSION 1.1
33 #endif
17 #endif 34 #endif
18 35
19 #include "vamp/vamp.h" 36 #include "vamp/vamp.h"
20 #include "vamp-sdk/PluginAdapter.h" 37 #include "vamp-sdk/PluginAdapter.h"
21 #include "PyPlugScanner.h" 38 #include "PyPlugScanner.h"
39 using std::string; 56 using std::string;
40 using std::vector; 57 using std::vector;
41 58
42 static int adinstcount; 59 static int adinstcount;
43 static int totinstcount; 60 static int totinstcount;
61 static bool numpyInstalled = false;
62 static bool arrayApiInitialised = false;
44 63
45 class PyPluginAdapter : public Vamp::PluginAdapterBase 64 class PyPluginAdapter : public Vamp::PluginAdapterBase
46 { 65 {
47 public: 66 public:
48 PyPluginAdapter(std::string pyPlugId, PyObject* pyClass) : 67 PyPluginAdapter(std::string pyPlugId, PyObject* pyClass) :
64 83
65 protected: 84 protected:
66 Vamp::Plugin *createPlugin(float inputSampleRate) 85 Vamp::Plugin *createPlugin(float inputSampleRate)
67 { 86 {
68 try { 87 try {
69 PyPlugin *plugin = new PyPlugin(m_plug, inputSampleRate, m_pyClass, totinstcount); 88 PyPlugin *plugin = new PyPlugin(m_plug, inputSampleRate, m_pyClass, totinstcount, numpyInstalled);
70 return plugin; 89 return plugin;
71 } catch (...) { 90 } catch (...) {
72 cerr << "PyPluginAdapter::createPlugin: Failed to construct PyPlugin" << endl; 91 cerr << "PyPluginAdapter::createPlugin: Failed to construct PyPlugin" << endl;
73 // any plugin with syntax errors will fail to construct 92 // any plugin with syntax errors will fail to construct
74 m_failed = true; 93 m_failed = true;
79 std::string m_plug; 98 std::string m_plug;
80 PyObject *m_pyClass; 99 PyObject *m_pyClass;
81 bool m_failed; 100 bool m_failed;
82 }; 101 };
83 102
103
84 static void array_API_initialiser() 104 static void array_API_initialiser()
85 { 105 {
86 /// numpy C-API requirement 106 if (arrayApiInitialised) return;
107
108 /* Numpy 1.3 build note: there seems to be a bug
109 in this version (at least on OS/X) which will cause memory
110 access error in the array API import function if an earlier runtime
111 version of Numpy is used when loading the library.
112 (below is a horrible workaround)
113 */
114
87 #ifdef HAVE_NUMPY 115 #ifdef HAVE_NUMPY
116
117 string ver;
118 float numpyVersion;
119
120 /// attmept to test numpy version before importing the array API
121 cerr << "Numpy build information: ABI level: " << NPY_VERSION
122 << " Numpy version: " << NUMPY_SHORTVERSION << endl;
123
124 PyObject *pyModule, *pyDict, *pyVer;
125
126 pyModule = PyImport_ImportModule("numpy"); //numpy.core.multiarray
127 if (!pyModule) {
128 cerr << "Vampy was compiled with Numpy support but Numpy does not seem to be installed." << endl;
129 #ifdef __APPLE__
130 cerr << "Hint: Check if Numpy is installed for the particular setup of Python used by Vampy (given by Python exec prefix)." << endl;
131 #endif
132 goto numpyFailure;
133 }
134
135 pyDict = PyModule_GetDict(pyModule); // borrowed ref
136 if (!pyDict) {
137 cerr << "Can not access Numpy module dictionary." << endl;
138 goto numpyFailure;
139 }
140
141 pyVer = PyDict_GetItemString(pyDict,"__version__"); //borrowed ref
142 if (!pyVer) {
143 cerr << "Can not access Numpy version information." << endl;
144 goto numpyFailure;
145 }
146
147 ver = PyString_AsString(pyVer);
148 ver = ver.substr(0,ver.rfind("."));
149 if(EOF == sscanf(ver.c_str(), "%f", &numpyVersion))
150 {
151 cerr << "Could not parse Numpy version information." << endl;
152 goto numpyFailure;
153 }
154
155 cerr << "Numpy runtime version: " << numpyVersion << endl;
156 if (numpyVersion < (float) NUMPY_SHORTVERSION) {
157 cerr << "Incompatible Numpy version found: " << numpyVersion << endl;
158 goto numpyFailure;
159 }
160
161 Py_DECREF(pyModule);
162
163 // At least we catch import errors, but if binary compatibility
164 // has changed without notice, this would still fail.
165 // However, we should never get to this point now anyway.
88 import_array(); 166 import_array();
89 if(NPY_VERSION != PyArray_GetNDArrayCVersion()) 167 if (PyErr_Occurred()) {
90 cerr << "Warning: Numpy ABI version mismatch. (Build version: " 168 cerr << "Import error while loading the Numpy Array API." << endl;
91 << NPY_VERSION << " Runtime version: " << PyArray_GetNDArrayCVersion() << ")" << endl; 169 PyErr_Print(); PyErr_Clear();
92 #endif 170 goto numpyFailure;
171 }
172 else {
173
174 #ifdef _DEBUG
175 if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {
176 // the Import function does this check already.
177 cerr << "Warning: Numpy version mismatch. (Build version: "
178 << NPY_VERSION << " Runtime version: " << PyArray_GetNDArrayCVersion() << ")" << endl;
179 goto numpyFailure;
180 }
181 #endif
182
183 numpyInstalled = true;
184 arrayApiInitialised = true;
185 return;
186 }
187
188
189 numpyFailure:
190 cerr << "Please make sure you have Numpy " << NUMPY_SHORTVERSION << " or greater installed." << endl;
191 cerr << "Vampy: Numpy support disabled." << endl;
192 numpyInstalled = false;
193 arrayApiInitialised = true;
194 if (pyModule) Py_XDECREF(pyModule);
195 return;
196
197 /*HAVE_NUMPY*/
198 #endif
199
200 numpyInstalled = false;
201 arrayApiInitialised = true;
202 return;
93 } 203 }
94 204
95 205
96 static std::vector<PyPluginAdapter *> adapters; 206 static std::vector<PyPluginAdapter *> adapters;
97 static bool haveScannedPlugins = false; 207 static bool haveScannedPlugins = false;
185 if (!preloadPython()) 295 if (!preloadPython())
186 cerr << "Warning: Could not preload Python. Dynamic loading in scripts will fail." << endl; 296 cerr << "Warning: Could not preload Python. Dynamic loading in scripts will fail." << endl;
187 if (PyImport_AppendInittab("vampy",initvampy) != 0) 297 if (PyImport_AppendInittab("vampy",initvampy) != 0)
188 cerr << "Warning: Extension module could not be added to module inittab." << endl; 298 cerr << "Warning: Extension module could not be added to module inittab." << endl;
189 Py_Initialize(); 299 Py_Initialize();
300 array_API_initialiser();
190 initvampy(); 301 initvampy();
191 #ifdef _DEBUG 302 #ifdef _DEBUG
192 cerr << "# isPythonInitialized after initialize: " << Py_IsInitialized() << endl; 303 cerr << "# isPythonInitialized after initialize: " << Py_IsInitialized() << endl;
193 #endif 304 #endif
194 } 305 }