# HG changeset patch # User Chris Cannam # Date 1416999383 0 # Node ID 7e7f2f7d954225d3516733c3982067fc474959f6 # Parent 1175e814954ed91a31c6b1f6b81552e2a63f4db3 PyTypeConversions -> VectorConversion diff -r 1175e814954e -r 7e7f2f7d9542 Makefile --- a/Makefile Wed Nov 26 10:54:48 2014 +0000 +++ b/Makefile Wed Nov 26 10:56:23 2014 +0000 @@ -7,7 +7,7 @@ LDFLAGS := -shared -Wl,-Bstatic -lvamp-hostsdk -Wl,-Bdynamic -Wl,-z,defs -lpython2.7 -ldl -OBJECTS := PyRealTime.o PyTypeConversions.o vampyhost.o +OBJECTS := PyRealTime.o VectorConversion.o vampyhost.o all: vampyhost.so @@ -24,5 +24,5 @@ # DO NOT DELETE PyRealTime.o: PyRealTime.h -PyTypeConversions.o: PyTypeConversions.h -vampyhost.o: PyRealTime.h PyTypeConversions.h +vampyhost.o: PyRealTime.h VectorConversion.h +VectorConversion.o: VectorConversion.h diff -r 1175e814954e -r 7e7f2f7d9542 PyTypeConversions.cpp --- a/PyTypeConversions.cpp Wed Nov 26 10:54:48 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,264 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - VampyHost - - Use Vamp audio analysis plugins in Python - - Gyorgy Fazekas and Chris Cannam - Centre for Digital Music, Queen Mary, University of London - Copyright 2008-2014 Queen Mary, University of London - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and the authors - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -#include - -#include "PyTypeConversions.h" - -#include -#include - -using namespace std; - -/* Note: NO FUNCTION IN THIS CLASS SHOULD ALTER REFERENCE COUNTS - (EXCEPT FOR TEMPORARY PYTHON OBJECTS)! */ - -PyTypeConversions::PyTypeConversions() : - m_error(false), - error(m_error) // const public reference for easy access -{ -} - -PyTypeConversions::~PyTypeConversions() -{ -} - -/// floating point numbers (TODO: check numpy.float128) -float -PyTypeConversions::PyValue_To_Float(PyObject* pyValue) const -{ - // convert float - if (pyValue && PyFloat_Check(pyValue)) - //TODO: check for limits here (same on most systems) - return (float) PyFloat_AS_DOUBLE(pyValue); - - if (pyValue == NULL) - { - setValueError("Error while converting object " + PyValue_Get_TypeName(pyValue) + " to float. "); - return 0.0; - } - - setValueError("Conversion error: object" + PyValue_Get_TypeName(pyValue) +" is not float."); - return 0.0; -} - -vector -PyTypeConversions::PyValue_To_FloatVector (PyObject *pyValue) const -{ - /// numpy array - if (PyArray_CheckExact(pyValue)) - return PyArray_To_FloatVector(pyValue); - - /// python list of floats (backward compatible) - if (PyList_Check(pyValue)) { - return PyList_To_FloatVector(pyValue); - } - - string msg = "Value is not list or array of floats"; - setValueError(msg); -#ifdef _DEBUG - cerr << "PyTypeConversions::PyValue_To_FloatVector failed. " << msg << endl; -#endif - return vector(); -} - -vector -PyTypeConversions::PyList_To_FloatVector (PyObject *inputList) const -{ - vector v; - - if (!PyList_Check(inputList)) { - setValueError("Value is not a list"); - return v; - } - - PyObject **pyObjectArray = PySequence_Fast_ITEMS(inputList); - int n = PyList_GET_SIZE(inputList); - - for (int i = 0; i < n; ++i) { - v.push_back(PyValue_To_Float(pyObjectArray[i])); - } - - return v; -} - -vector -PyTypeConversions::PyArray_To_FloatVector (PyObject *pyValue) const -{ - vector v; - - if (!PyArray_Check(pyValue)) { - setValueError("Value is not an array"); - return v; - } - - PyArrayObject* pyArray = (PyArrayObject*) pyValue; - PyArray_Descr* descr = PyArray_DESCR(pyArray); - - if (PyArray_DATA(pyArray) == 0 || descr == 0) { - string msg = "NumPy array with NULL data or descriptor pointer encountered."; - setValueError(msg); - return v; - } - - if (PyArray_NDIM(pyArray) != 1) { - string msg = "NumPy array must be a one dimensional vector."; - setValueError(msg); - return v; - } - - /// check strides (useful if array is not continuous) - size_t strides = *((size_t*) PyArray_STRIDES(pyArray)); - - /// convert the array - switch (descr->type_num) { - - case NPY_FLOAT : // dtype='float32' - return PyArray_Convert(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides); - case NPY_DOUBLE : // dtype='float64' - return PyArray_Convert(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides); - case NPY_INT : // dtype='int' - return PyArray_Convert(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides); - case NPY_LONG : // dtype='long' - return PyArray_Convert(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides); - default : - string msg = "Unsupported value type in NumPy array object."; - setValueError(msg); -#ifdef _DEBUG - cerr << "PyTypeConversions::PyArray_To_FloatVector failed. Error: " << msg << endl; -#endif - return v; - } -} - -PyObject * -PyTypeConversions::PyArray_From_FloatVector(const vector &v) const -{ - npy_intp ndims[1]; - ndims[0] = (int)v.size(); - PyObject *arr = PyArray_SimpleNew(1, ndims, NPY_FLOAT); - float *data = (float *)PyArray_DATA((PyArrayObject *)arr); - for (int i = 0; i < ndims[0]; ++i) { - data[i] = v[i]; - } - return arr; -} - -PyObject * -PyTypeConversions::PyValue_From_StringVector(const vector &v) const -{ - PyObject *pyList = PyList_New(v.size()); - for (size_t i = 0; i < v.size(); ++i) { - PyObject *pyStr = PyString_FromString(v[i].c_str()); - PyList_SET_ITEM(pyList, i, pyStr); - } - return pyList; -} - - -/* Error handling */ - -void -PyTypeConversions::setValueError (string message) const -{ - m_error = true; - m_errorQueue.push(ValueError(message)); -} - -/// return a reference to the last error or creates a new one. -ValueError& -PyTypeConversions::lastError() const -{ - m_error = false; - if (!m_errorQueue.empty()) return m_errorQueue.back(); - else { - m_errorQueue.push(ValueError("Type conversion error.")); - return m_errorQueue.back(); - } -} - -/// helper function to iterate over the error message queue: -/// pops the oldest item -ValueError -PyTypeConversions::getError() const -{ - if (!m_errorQueue.empty()) { - ValueError e = m_errorQueue.front(); - m_errorQueue.pop(); - if (m_errorQueue.empty()) m_error = false; - return e; - } - else { - m_error = false; - return ValueError(); - } -} - -/* Utilities */ - -/// get the type name of an object -string -PyTypeConversions::PyValue_Get_TypeName(PyObject* pyValue) const -{ - PyObject *pyType = PyObject_Type(pyValue); - if (!pyType) - { - cerr << "Warning: Object type name could not be found." << endl; - if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();} - return string ("< unknown type >"); - } - PyObject *pyString = PyObject_Str(pyType); - if (!pyString) - { - cerr << "Warning: Object type name could not be found." << endl; - if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();} - Py_CLEAR(pyType); - return string ("< unknown type >"); - } - char *cstr = PyString_AS_STRING(pyString); - if (!cstr) - { - cerr << "Warning: Object type name could not be found." << endl; - if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();} - Py_DECREF(pyType); - Py_CLEAR(pyString); - return string("< unknown type >"); - } - Py_DECREF(pyType); - Py_DECREF(pyString); - return string(cstr); -} diff -r 1175e814954e -r 7e7f2f7d9542 PyTypeConversions.h --- a/PyTypeConversions.h Wed Nov 26 10:54:48 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - VampyHost - - Use Vamp audio analysis plugins in Python - - Gyorgy Fazekas and Chris Cannam - Centre for Digital Music, Queen Mary, University of London - Copyright 2008-2014 Queen Mary, University of London - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the names of the Centre for - Digital Music; Queen Mary, University of London; and the authors - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in this Software without prior written - authorization. -*/ - -/* - PyTypeConversions: Type safe conversion utilities between Python - types and basic C/C++ types. -*/ - -#ifndef PY_TYPE_CONVERSIONS_H -#define PY_TYPE_CONVERSIONS_H - -#include - -// NumPy is required here -#define PY_ARRAY_UNIQUE_SYMBOL VAMPYHOST_ARRAY_API -#define NO_IMPORT_ARRAY -#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION -#include "numpy/arrayobject.h" - -#include -#include -#include -#include -#include - -// Data -class ValueError -{ -public: - ValueError() {} - ValueError(std::string m) : message(m) {} - std::string location; - std::string message; - std::string str() const { - return (location.empty()) ? message : message + "\nLocation: " + location;} - template ValueError &operator<< (const V& v) - { - std::ostringstream ss; - ss << v; - location += ss.str(); - return *this; - } -}; - -class PyTypeConversions -{ -public: - PyTypeConversions(); - ~PyTypeConversions(); - - ValueError getError() const; - - std::vector PyValue_To_FloatVector (PyObject*) const; - std::vector PyArray_To_FloatVector (PyObject *) const; - std::vector PyList_To_FloatVector (PyObject*) const; - - PyObject *PyValue_From_StringVector(const std::vector &) const; - PyObject *PyArray_From_FloatVector(const std::vector &) const; - -private: - std::string PyValue_Get_TypeName(PyObject*) const; - float PyValue_To_Float(PyObject*) const; - - /// Convert DTYPE type 1D NumpyArray to std::vector - template - std::vector PyArray_Convert(void* raw_data_ptr, - int length, - size_t strides) const { - - std::vector v(length); - - /// check if the array is continuous, if not use strides info - if (sizeof(DTYPE) != strides) { -#ifdef _DEBUG_VALUES - cerr << "Warning: discontinuous numpy array. Strides: " << strides << " bytes. sizeof(dtype): " << sizeof(DTYPE) << endl; -#endif - char* data = (char*) raw_data_ptr; - for (int i = 0; i < length; ++i){ - v[i] = (RET)(*((DTYPE*)data)); - data += strides; - } - return v; - } - - DTYPE* data = (DTYPE*) raw_data_ptr; - for (int i = 0; i < length; ++i){ - v[i] = (RET)data[i]; - } - - return v; - } - -private: - mutable bool m_error; - mutable std::queue m_errorQueue; - - void setValueError(std::string) const; - ValueError& lastError() const; - -public: - const bool& error; -}; - -#endif diff -r 1175e814954e -r 7e7f2f7d9542 VectorConversion.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VectorConversion.cpp Wed Nov 26 10:56:23 2014 +0000 @@ -0,0 +1,264 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + VampyHost + + Use Vamp audio analysis plugins in Python + + Gyorgy Fazekas and Chris Cannam + Centre for Digital Music, Queen Mary, University of London + Copyright 2008-2014 Queen Mary, University of London + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and the authors + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include + +#include "VectorConversion.h" + +#include +#include + +using namespace std; + +/* Note: NO FUNCTION IN THIS CLASS SHOULD ALTER REFERENCE COUNTS + (EXCEPT FOR TEMPORARY PYTHON OBJECTS)! */ + +VectorConversion::VectorConversion() : + m_error(false), + error(m_error) // const public reference for easy access +{ +} + +VectorConversion::~VectorConversion() +{ +} + +/// floating point numbers (TODO: check numpy.float128) +float +VectorConversion::PyValue_To_Float(PyObject* pyValue) const +{ + // convert float + if (pyValue && PyFloat_Check(pyValue)) + //TODO: check for limits here (same on most systems) + return (float) PyFloat_AS_DOUBLE(pyValue); + + if (pyValue == NULL) + { + setValueError("Error while converting object " + PyValue_Get_TypeName(pyValue) + " to float. "); + return 0.0; + } + + setValueError("Conversion error: object" + PyValue_Get_TypeName(pyValue) +" is not float."); + return 0.0; +} + +vector +VectorConversion::PyValue_To_FloatVector (PyObject *pyValue) const +{ + /// numpy array + if (PyArray_CheckExact(pyValue)) + return PyArray_To_FloatVector(pyValue); + + /// python list of floats (backward compatible) + if (PyList_Check(pyValue)) { + return PyList_To_FloatVector(pyValue); + } + + string msg = "Value is not list or array of floats"; + setValueError(msg); +#ifdef _DEBUG + cerr << "VectorConversion::PyValue_To_FloatVector failed. " << msg << endl; +#endif + return vector(); +} + +vector +VectorConversion::PyList_To_FloatVector (PyObject *inputList) const +{ + vector v; + + if (!PyList_Check(inputList)) { + setValueError("Value is not a list"); + return v; + } + + PyObject **pyObjectArray = PySequence_Fast_ITEMS(inputList); + int n = PyList_GET_SIZE(inputList); + + for (int i = 0; i < n; ++i) { + v.push_back(PyValue_To_Float(pyObjectArray[i])); + } + + return v; +} + +vector +VectorConversion::PyArray_To_FloatVector (PyObject *pyValue) const +{ + vector v; + + if (!PyArray_Check(pyValue)) { + setValueError("Value is not an array"); + return v; + } + + PyArrayObject* pyArray = (PyArrayObject*) pyValue; + PyArray_Descr* descr = PyArray_DESCR(pyArray); + + if (PyArray_DATA(pyArray) == 0 || descr == 0) { + string msg = "NumPy array with NULL data or descriptor pointer encountered."; + setValueError(msg); + return v; + } + + if (PyArray_NDIM(pyArray) != 1) { + string msg = "NumPy array must be a one dimensional vector."; + setValueError(msg); + return v; + } + + /// check strides (useful if array is not continuous) + size_t strides = *((size_t*) PyArray_STRIDES(pyArray)); + + /// convert the array + switch (descr->type_num) { + + case NPY_FLOAT : // dtype='float32' + return PyArray_Convert(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides); + case NPY_DOUBLE : // dtype='float64' + return PyArray_Convert(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides); + case NPY_INT : // dtype='int' + return PyArray_Convert(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides); + case NPY_LONG : // dtype='long' + return PyArray_Convert(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides); + default : + string msg = "Unsupported value type in NumPy array object."; + setValueError(msg); +#ifdef _DEBUG + cerr << "VectorConversion::PyArray_To_FloatVector failed. Error: " << msg << endl; +#endif + return v; + } +} + +PyObject * +VectorConversion::PyArray_From_FloatVector(const vector &v) const +{ + npy_intp ndims[1]; + ndims[0] = (int)v.size(); + PyObject *arr = PyArray_SimpleNew(1, ndims, NPY_FLOAT); + float *data = (float *)PyArray_DATA((PyArrayObject *)arr); + for (int i = 0; i < ndims[0]; ++i) { + data[i] = v[i]; + } + return arr; +} + +PyObject * +VectorConversion::PyValue_From_StringVector(const vector &v) const +{ + PyObject *pyList = PyList_New(v.size()); + for (size_t i = 0; i < v.size(); ++i) { + PyObject *pyStr = PyString_FromString(v[i].c_str()); + PyList_SET_ITEM(pyList, i, pyStr); + } + return pyList; +} + + +/* Error handling */ + +void +VectorConversion::setValueError (string message) const +{ + m_error = true; + m_errorQueue.push(ValueError(message)); +} + +/// return a reference to the last error or creates a new one. +ValueError& +VectorConversion::lastError() const +{ + m_error = false; + if (!m_errorQueue.empty()) return m_errorQueue.back(); + else { + m_errorQueue.push(ValueError("Type conversion error.")); + return m_errorQueue.back(); + } +} + +/// helper function to iterate over the error message queue: +/// pops the oldest item +ValueError +VectorConversion::getError() const +{ + if (!m_errorQueue.empty()) { + ValueError e = m_errorQueue.front(); + m_errorQueue.pop(); + if (m_errorQueue.empty()) m_error = false; + return e; + } + else { + m_error = false; + return ValueError(); + } +} + +/* Utilities */ + +/// get the type name of an object +string +VectorConversion::PyValue_Get_TypeName(PyObject* pyValue) const +{ + PyObject *pyType = PyObject_Type(pyValue); + if (!pyType) + { + cerr << "Warning: Object type name could not be found." << endl; + if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();} + return string ("< unknown type >"); + } + PyObject *pyString = PyObject_Str(pyType); + if (!pyString) + { + cerr << "Warning: Object type name could not be found." << endl; + if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();} + Py_CLEAR(pyType); + return string ("< unknown type >"); + } + char *cstr = PyString_AS_STRING(pyString); + if (!cstr) + { + cerr << "Warning: Object type name could not be found." << endl; + if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();} + Py_DECREF(pyType); + Py_CLEAR(pyString); + return string("< unknown type >"); + } + Py_DECREF(pyType); + Py_DECREF(pyString); + return string(cstr); +} diff -r 1175e814954e -r 7e7f2f7d9542 VectorConversion.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VectorConversion.h Wed Nov 26 10:56:23 2014 +0000 @@ -0,0 +1,138 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + VampyHost + + Use Vamp audio analysis plugins in Python + + Gyorgy Fazekas and Chris Cannam + Centre for Digital Music, Queen Mary, University of London + Copyright 2008-2014 Queen Mary, University of London + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and the authors + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +/* + VectorConversion: A handful of type safe conversion utilities + between Python types and C++ vectors. +*/ + +#ifndef PY_TYPE_CONVERSIONS_H +#define PY_TYPE_CONVERSIONS_H + +#include + +// NumPy is required here +#define PY_ARRAY_UNIQUE_SYMBOL VAMPYHOST_ARRAY_API +#define NO_IMPORT_ARRAY +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include "numpy/arrayobject.h" + +#include +#include +#include +#include +#include + +// Data +class ValueError +{ +public: + ValueError() {} + ValueError(std::string m) : message(m) {} + std::string location; + std::string message; + std::string str() const { + return (location.empty()) ? message : message + "\nLocation: " + location;} + template ValueError &operator<< (const V& v) + { + std::ostringstream ss; + ss << v; + location += ss.str(); + return *this; + } +}; + +class VectorConversion +{ +public: + VectorConversion(); + ~VectorConversion(); + + ValueError getError() const; + + std::vector PyValue_To_FloatVector (PyObject*) const; + std::vector PyArray_To_FloatVector (PyObject *) const; + std::vector PyList_To_FloatVector (PyObject*) const; + + PyObject *PyValue_From_StringVector(const std::vector &) const; + PyObject *PyArray_From_FloatVector(const std::vector &) const; + +private: + std::string PyValue_Get_TypeName(PyObject*) const; + float PyValue_To_Float(PyObject*) const; + + /// Convert DTYPE type 1D NumpyArray to std::vector + template + std::vector PyArray_Convert(void* raw_data_ptr, + int length, + size_t strides) const { + + std::vector v(length); + + /// check if the array is continuous, if not use strides info + if (sizeof(DTYPE) != strides) { +#ifdef _DEBUG_VALUES + cerr << "Warning: discontinuous numpy array. Strides: " << strides << " bytes. sizeof(dtype): " << sizeof(DTYPE) << endl; +#endif + char* data = (char*) raw_data_ptr; + for (int i = 0; i < length; ++i){ + v[i] = (RET)(*((DTYPE*)data)); + data += strides; + } + return v; + } + + DTYPE* data = (DTYPE*) raw_data_ptr; + for (int i = 0; i < length; ++i){ + v[i] = (RET)data[i]; + } + + return v; + } + +private: + mutable bool m_error; + mutable std::queue m_errorQueue; + + void setValueError(std::string) const; + ValueError& lastError() const; + +public: + const bool& error; +}; + +#endif diff -r 1175e814954e -r 7e7f2f7d9542 vampyhost.cpp --- a/vampyhost.cpp Wed Nov 26 10:54:48 2014 +0000 +++ b/vampyhost.cpp Wed Nov 26 10:56:23 2014 +0000 @@ -56,7 +56,7 @@ #include "vamp-hostsdk/PluginInputDomainAdapter.h" #include "vamp-hostsdk/PluginLoader.h" -#include "PyTypeConversions.h" +#include "VectorConversion.h" #include "PyRealTime.h" #include @@ -135,7 +135,7 @@ PluginLoader *loader = PluginLoader::getInstance(); vector plugins = loader->listPlugins(); - PyTypeConversions conv; + VectorConversion conv; return conv.PyValue_From_StringVector(plugins); } @@ -145,7 +145,7 @@ cerr << "vampyhost_getPluginPath" << endl; vector path = PluginHostAdapter::getPluginPath(); - PyTypeConversions conv; + VectorConversion conv; return conv.PyValue_From_StringVector(path); } @@ -207,7 +207,7 @@ PluginLoader::PluginCategoryHierarchy category = loader->getPluginCategory(pluginKey); - PyTypeConversions conv; + VectorConversion conv; return conv.PyValue_From_StringVector(category); } @@ -441,7 +441,7 @@ float **inbuf = new float *[channels]; - PyTypeConversions typeConv; + VectorConversion typeConv; cerr << "here!" << endl; @@ -472,7 +472,7 @@ cerr << "no no no, here!" << endl; - PyTypeConversions conv; + VectorConversion conv; PyObject *pyFs = PyDict_New();