Mercurial > hg > vampy
comparison vampy-main.cpp @ 67:146d14ab15e7
Debug output: off by default, on with VAMPY_VERBOSE environment variable
author | Chris Cannam |
---|---|
date | Mon, 17 Nov 2014 10:03:44 +0000 |
parents | 5664fe298af2 |
children | 6c755f3e1173 |
comparison
equal
deleted
inserted
replaced
66:5664fe298af2 | 67:146d14ab15e7 |
---|---|
39 #include "vamp-sdk/PluginAdapter.h" | 39 #include "vamp-sdk/PluginAdapter.h" |
40 #include "PyPlugScanner.h" | 40 #include "PyPlugScanner.h" |
41 #include "PyPlugin.h" | 41 #include "PyPlugin.h" |
42 #include "PyExtensionModule.h" | 42 #include "PyExtensionModule.h" |
43 #include "PyExtensionManager.h" | 43 #include "PyExtensionManager.h" |
44 #include "Debug.h" | |
44 #include <sstream> | 45 #include <sstream> |
45 | 46 |
46 #ifdef _WIN32 | 47 #ifdef _WIN32 |
47 #define pathsep ('\\') | 48 #define pathsep ('\\') |
48 #include <windows.h> | 49 #include <windows.h> |
70 PluginAdapterBase(), | 71 PluginAdapterBase(), |
71 m_plug(pyPlugId), | 72 m_plug(pyPlugId), |
72 m_pyClass(pyClass), | 73 m_pyClass(pyClass), |
73 m_failed(false) | 74 m_failed(false) |
74 { | 75 { |
75 cerr << "PyPluginAdapter:ctor:"<< adinstcount << ": " << m_plug << endl; | 76 DSTREAM << "PyPluginAdapter:ctor:"<< adinstcount << ": " << m_plug << endl; |
76 adinstcount++; | 77 adinstcount++; |
77 } | 78 } |
78 | 79 |
79 ~PyPluginAdapter() | 80 ~PyPluginAdapter() |
80 { | 81 { |
88 { | 89 { |
89 try { | 90 try { |
90 PyPlugin *plugin = new PyPlugin(m_plug, inputSampleRate, m_pyClass, totinstcount, numpyInstalled); | 91 PyPlugin *plugin = new PyPlugin(m_plug, inputSampleRate, m_pyClass, totinstcount, numpyInstalled); |
91 return plugin; | 92 return plugin; |
92 } catch (...) { | 93 } catch (...) { |
93 cerr << "PyPluginAdapter::createPlugin: Failed to construct PyPlugin" << endl; | 94 cerr << "ERROR: PyPluginAdapter::createPlugin: Failed to construct PyPlugin" << endl; |
94 // any plugin with syntax errors will fail to construct | 95 // any plugin with syntax errors will fail to construct |
95 m_failed = true; | 96 m_failed = true; |
96 return 0; | 97 return 0; |
97 } | 98 } |
98 } | 99 } |
99 | 100 |
100 std::string m_plug; | 101 std::string m_plug; |
119 string ver; | 120 string ver; |
120 std::istringstream verStream; | 121 std::istringstream verStream; |
121 float numpyVersion; | 122 float numpyVersion; |
122 | 123 |
123 /// attmept to test numpy version before importing the array API | 124 /// attmept to test numpy version before importing the array API |
124 cerr << "Numpy build information: ABI level: " << NPY_VERSION | 125 DSTREAM << "Numpy build information: ABI level: " << NPY_VERSION |
125 << " Numpy version: " << NUMPY_SHORTVERSION << endl; | 126 << " Numpy version: " << NUMPY_SHORTVERSION << endl; |
126 | 127 |
127 PyObject *pyModule, *pyDict, *pyVer; | 128 PyObject *pyModule, *pyDict, *pyVer; |
128 | 129 |
129 pyModule = PyImport_ImportModule("numpy"); //numpy.core.multiarray | 130 pyModule = PyImport_ImportModule("numpy"); //numpy.core.multiarray |
130 if (!pyModule) { | 131 if (!pyModule) { |
131 cerr << "Vampy was compiled with Numpy support but Numpy does not seem to be installed." << endl; | 132 cerr << "ERROR: Vampy was compiled with Numpy support but Numpy does not seem to be installed." << endl; |
132 #ifdef __APPLE__ | 133 #ifdef __APPLE__ |
133 cerr << "Hint: Check if Numpy is installed for the particular setup of Python used by Vampy (given by Python exec prefix)." << endl; | 134 cerr << "Hint: Check if Numpy is installed for the particular setup of Python used by Vampy (given by Python exec prefix)." << endl; |
134 #endif | 135 #endif |
135 goto numpyFailure; | 136 goto numpyFailure; |
136 } | 137 } |
137 | 138 |
138 pyDict = PyModule_GetDict(pyModule); // borrowed ref | 139 pyDict = PyModule_GetDict(pyModule); // borrowed ref |
139 if (!pyDict) { | 140 if (!pyDict) { |
140 cerr << "Can not access Numpy module dictionary." << endl; | 141 cerr << "ERROR: Can not access Numpy module dictionary." << endl; |
141 goto numpyFailure; | 142 goto numpyFailure; |
142 } | 143 } |
143 | 144 |
144 pyVer = PyDict_GetItemString(pyDict,"__version__"); //borrowed ref | 145 pyVer = PyDict_GetItemString(pyDict,"__version__"); //borrowed ref |
145 if (!pyVer) { | 146 if (!pyVer) { |
146 cerr << "Can not access Numpy version information." << endl; | 147 cerr << "ERROR: Can not access Numpy version information." << endl; |
147 goto numpyFailure; | 148 goto numpyFailure; |
148 } | 149 } |
149 | 150 |
150 ver = PyString_AsString(pyVer); | 151 ver = PyString_AsString(pyVer); |
151 ver = ver.substr(0,ver.rfind(".")); | 152 ver = ver.substr(0,ver.rfind(".")); |
152 /* | 153 |
153 Applied patch from here: http://vamp-plugins.org/forum/index.php/topic,162.msg387.html#msg387 to replace this: | |
154 if(EOF == sscanf(ver.c_str(), "%f", &numpyVersion)) | |
155 { | |
156 cerr << "Could not parse Numpy version information." << endl; | |
157 goto numpyFailure; | |
158 }*/ | |
159 // parse version string to float | 154 // parse version string to float |
160 verStream.str(ver); | 155 verStream.str(ver); |
161 verStream >> numpyVersion; | 156 verStream >> numpyVersion; |
162 | 157 |
163 cerr << "Numpy runtime version: " << numpyVersion << endl; | 158 DSTREAM << "Numpy runtime version: " << numpyVersion << endl; |
164 if (numpyVersion < (float) NUMPY_SHORTVERSION) { | 159 if (numpyVersion < (float) NUMPY_SHORTVERSION) { |
165 cerr << "Incompatible Numpy version found: " << numpyVersion << endl; | 160 cerr << "ERROR: Incompatible Numpy version found: " << numpyVersion << endl; |
166 goto numpyFailure; | 161 goto numpyFailure; |
167 } | 162 } |
168 | 163 |
169 Py_DECREF(pyModule); | 164 Py_DECREF(pyModule); |
170 | 165 |
171 // At least we catch import errors, but if binary compatibility | 166 // At least we catch import errors, but if binary compatibility |
172 // has changed without notice, this would still fail. | 167 // has changed without notice, this would still fail. |
173 // However, we should never get to this point now anyway. | 168 // However, we should never get to this point now anyway. |
174 import_array(); | 169 import_array(); |
175 if (PyErr_Occurred()) { | 170 if (PyErr_Occurred()) { |
176 cerr << "Import error while loading the Numpy Array API." << endl; | 171 cerr << "ERROR: Import error while loading the Numpy Array API." << endl; |
177 PyErr_Print(); PyErr_Clear(); | 172 PyErr_Print(); PyErr_Clear(); |
178 goto numpyFailure; | 173 goto numpyFailure; |
179 } | 174 } |
180 else { | 175 else { |
181 | |
182 #ifdef _DEBUG | |
183 if (NPY_VERSION != PyArray_GetNDArrayCVersion()) { | |
184 // the Import function does this check already. | |
185 cerr << "Warning: Numpy version mismatch. (Build version: " | |
186 << NPY_VERSION << " Runtime version: " << PyArray_GetNDArrayCVersion() << ")" << endl; | |
187 goto numpyFailure; | |
188 } | |
189 #endif | |
190 | |
191 numpyInstalled = true; | 176 numpyInstalled = true; |
192 arrayApiInitialised = true; | 177 arrayApiInitialised = true; |
193 return; | 178 return; |
194 } | 179 } |
195 | 180 |
227 if (!lib) { | 212 if (!lib) { |
228 //perror("dlopen"); | 213 //perror("dlopen"); |
229 return false; | 214 return false; |
230 } | 215 } |
231 #endif | 216 #endif |
232 cerr << "Preloaded Python from " << name << endl; | 217 DSTREAM << "Preloaded Python from " << name << endl; |
233 return true; | 218 return true; |
234 } | 219 } |
235 | 220 |
236 static bool preloadPython() | 221 static bool preloadPython() |
237 { | 222 { |
249 shortver = pyver.substr(0, i); | 234 shortver = pyver.substr(0, i); |
250 break; | 235 break; |
251 } | 236 } |
252 } | 237 } |
253 } | 238 } |
254 cerr << "Short version: " << shortver << endl; | 239 DSTREAM << "Short version: " << shortver << endl; |
255 // this is useful to find out where the loaded library might be loaded from | 240 // this is useful to find out where the loaded library might be loaded from |
256 cerr << "Python exec prefix: " << Py_GetExecPrefix() << endl; | 241 DSTREAM << "Python exec prefix: " << Py_GetExecPrefix() << endl; |
257 | 242 |
258 char *pylib = getenv("VAMPY_PYLIB"); | 243 char *pylib = getenv("VAMPY_PYLIB"); |
259 if (pylib && *pylib) { | 244 if (pylib && *pylib) { |
260 cerr << "Trying to preload Python from specified location " << pylib | 245 DSTREAM << "Trying to preload Python from specified location " << pylib |
261 << "..." << endl; | 246 << "..." << endl; |
262 return tryPreload(string(pylib)); | 247 return tryPreload(string(pylib)); |
263 } | 248 } |
264 | 249 |
265 vector<string> pfxs; | 250 vector<string> pfxs; |
266 pfxs.push_back(string(Py_GetExecPrefix()) + "/"); | 251 pfxs.push_back(string(Py_GetExecPrefix()) + "/"); |
303 *vampGetPluginDescriptor(unsigned int version,unsigned int index) | 288 *vampGetPluginDescriptor(unsigned int version,unsigned int index) |
304 { | 289 { |
305 if (version < 1) return 0; | 290 if (version < 1) return 0; |
306 | 291 |
307 int isPythonInitialized = Py_IsInitialized(); | 292 int isPythonInitialized = Py_IsInitialized(); |
308 cerr << "# isPythonInitialized: " << isPythonInitialized << endl; | 293 DSTREAM << "# isPythonInitialized: " << isPythonInitialized << endl; |
309 cerr << "# haveScannedPlugins: " << haveScannedPlugins << endl; | 294 DSTREAM << "# haveScannedPlugins: " << haveScannedPlugins << endl; |
310 | 295 |
311 if (!haveScannedPlugins) { | 296 if (!haveScannedPlugins) { |
312 | 297 |
313 if (!isPythonInitialized){ | 298 if (!isPythonInitialized){ |
314 | 299 |
317 if (PyImport_AppendInittab("vampy",initvampy) != 0) | 302 if (PyImport_AppendInittab("vampy",initvampy) != 0) |
318 cerr << "Warning: Extension module could not be added to module inittab." << endl; | 303 cerr << "Warning: Extension module could not be added to module inittab." << endl; |
319 Py_Initialize(); | 304 Py_Initialize(); |
320 array_API_initialiser(); | 305 array_API_initialiser(); |
321 initvampy(); | 306 initvampy(); |
322 #ifdef _DEBUG | 307 DSTREAM << "# isPythonInitialized after initialize: " << Py_IsInitialized() << endl; |
323 cerr << "# isPythonInitialized after initialize: " << Py_IsInitialized() << endl; | |
324 #endif | |
325 } | 308 } |
326 | 309 |
327 vector<string> pyPlugs; | 310 vector<string> pyPlugs; |
328 vector<string> pyPath; | 311 vector<string> pyPath; |
329 vector<PyObject *> pyClasses; | 312 vector<PyObject *> pyClasses; |
330 static PyPlugScanner *scanner; | 313 static PyPlugScanner *scanner; |
331 | 314 |
332 //Scanning Plugins | 315 //Scanning Plugins |
333 cerr << "Scanning Vampy Plugins" << endl; | 316 DSTREAM << "Scanning Vampy Plugins" << endl; |
334 scanner = PyPlugScanner::getInstance(); | 317 scanner = PyPlugScanner::getInstance(); |
335 | 318 |
336 // added env. varable support VAMPY_EXTPATH | 319 // added env. varable support VAMPY_EXTPATH |
337 pyPath=scanner->getAllValidPath(); | 320 pyPath=scanner->getAllValidPath(); |
338 scanner->setPath(pyPath); | 321 scanner->setPath(pyPath); |
339 | 322 |
340 // added env. variable support: | 323 // added env. variable support: |
341 // VAMPY_COMPILED=1 to recognise .pyc files (default is 1) | 324 // VAMPY_COMPILED=1 to recognise .pyc files (default is 1) |
342 pyPlugs = scanner->getPyPlugs(); | 325 pyPlugs = scanner->getPyPlugs(); |
343 | 326 |
344 cerr << "Found " << pyPlugs.size() << " Scripts." << endl; | 327 DSTREAM << "Found " << pyPlugs.size() << " Scripts." << endl; |
345 //TODO: should this support multiple classes per script (?) | 328 //TODO: should this support multiple classes per script (?) |
346 pyClasses = scanner->getPyClasses(); | 329 pyClasses = scanner->getPyClasses(); |
347 cerr << "Found " << pyClasses.size() << " Classes." << endl; | 330 DSTREAM << "Found " << pyClasses.size() << " Classes." << endl; |
348 | 331 |
349 for (size_t i = 0; i < pyPlugs.size(); ++i) { | 332 for (size_t i = 0; i < pyPlugs.size(); ++i) { |
350 adapters.push_back( new PyPluginAdapter(pyPlugs[i],pyClasses[i])); | 333 adapters.push_back( new PyPluginAdapter(pyPlugs[i],pyClasses[i])); |
351 } | 334 } |
352 pyExtensionManager.setPlugModuleNames(pyPlugs); | 335 pyExtensionManager.setPlugModuleNames(pyPlugs); |
353 pyExtensionManager.initExtension(); | 336 pyExtensionManager.initExtension(); |
354 array_API_initialiser(); | 337 array_API_initialiser(); |
355 haveScannedPlugins=true; | 338 haveScannedPlugins=true; |
356 } | 339 } |
357 | 340 |
358 #ifdef _DEBUG | 341 DSTREAM << "Accessing adapter index: " << index << " (adapters: " << adapters.size() << ")" << endl; |
359 cerr << "Accessing adapter index: " << index << " (adapters: " << adapters.size() << ")" << endl; | |
360 #endif | |
361 | 342 |
362 if (index<adapters.size()) { | 343 if (index<adapters.size()) { |
363 | 344 |
364 const VampPluginDescriptor *tmp = adapters[index]->getDescriptor(); | 345 const VampPluginDescriptor *tmp = adapters[index]->getDescriptor(); |
365 | 346 |