Chris@26: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@26: Chris@26: /* Chris@26: VampyHost Chris@26: Chris@26: Use Vamp audio analysis plugins in Python Chris@26: Chris@26: Gyorgy Fazekas and Chris Cannam Chris@26: Centre for Digital Music, Queen Mary, University of London Chris@26: Copyright 2008-2014 Queen Mary, University of London Chris@26: Chris@26: Permission is hereby granted, free of charge, to any person Chris@26: obtaining a copy of this software and associated documentation Chris@26: files (the "Software"), to deal in the Software without Chris@26: restriction, including without limitation the rights to use, copy, Chris@26: modify, merge, publish, distribute, sublicense, and/or sell copies Chris@26: of the Software, and to permit persons to whom the Software is Chris@26: furnished to do so, subject to the following conditions: Chris@26: Chris@26: The above copyright notice and this permission notice shall be Chris@26: included in all copies or substantial portions of the Software. Chris@26: Chris@26: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, Chris@26: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF Chris@26: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND Chris@26: NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR Chris@26: ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF Chris@26: CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION Chris@26: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Chris@26: Chris@26: Except as contained in this notice, the names of the Centre for Chris@26: Digital Music; Queen Mary, University of London; and the authors Chris@26: shall not be used in advertising or otherwise to promote the sale, Chris@26: use or other dealings in this Software without prior written Chris@26: authorization. Chris@26: */ Chris@26: Chris@26: /* Chris@26: PyTypeConversions: Type safe conversion utilities between Python Chris@26: types and basic C/C++ types. Chris@26: */ Chris@26: Chris@26: #ifndef PY_TYPE_CONVERSIONS_H Chris@26: #define PY_TYPE_CONVERSIONS_H Chris@26: Chris@26: #include Chris@26: Chris@26: #ifdef HAVE_NUMPY Chris@26: #define PY_ARRAY_UNIQUE_SYMBOL VAMPY_ARRAY_API Chris@26: #define NO_IMPORT_ARRAY Chris@26: #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION Chris@26: #include "numpy/arrayobject.h" Chris@26: #endif Chris@26: Chris@26: #include Chris@26: #include Chris@26: #include Chris@26: #include Chris@26: #include Chris@26: Chris@26: using std::cerr; Chris@26: using std::endl; Chris@26: Chris@26: #ifdef HAVE_NUMPY Chris@26: enum eArrayDataType { Chris@26: dtype_float32 = (int) NPY_FLOAT, Chris@26: dtype_complex64 = (int) NPY_CFLOAT Chris@26: }; Chris@26: #endif Chris@26: Chris@26: /* C++ mapping of PyNone Type */ Chris@26: struct NoneType {}; Chris@26: Chris@26: // Data Chris@26: class ValueError Chris@26: { Chris@26: public: Chris@26: ValueError() {} Chris@26: ValueError(std::string m, bool s) : message(m),strict(s) {} Chris@26: std::string location; Chris@26: std::string message; Chris@26: bool strict; Chris@26: std::string str() const { Chris@26: return (location.empty()) ? message : message + "\nLocation: " + location;} Chris@26: void print() const { cerr << str() << endl; } Chris@26: template ValueError &operator<< (const V& v) Chris@26: { Chris@26: std::ostringstream ss; Chris@26: ss << v; Chris@26: location += ss.str(); Chris@26: return *this; Chris@26: } Chris@26: }; Chris@26: Chris@26: class PyTypeConversions Chris@26: { Chris@26: public: Chris@26: PyTypeConversions(); Chris@26: ~PyTypeConversions(); Chris@26: Chris@26: // Utilities Chris@26: void setStrictTypingFlag(bool b) {m_strict = b;} Chris@26: void setNumpyInstalled(bool b) {m_numpyInstalled = b;} Chris@26: ValueError getError() const; Chris@26: std::string PyValue_Get_TypeName(PyObject*) const; Chris@26: Chris@26: // Basic type conversion: Python to C++ Chris@26: float PyValue_To_Float(PyObject*) const; Chris@26: size_t PyValue_To_Size_t(PyObject*) const; Chris@26: bool PyValue_To_Bool(PyObject*) const; Chris@26: std::string PyValue_To_String(PyObject*) const; Chris@26: long PyValue_To_Long(PyObject*) const; Chris@26: // int PyValue_To_Int(PyObject* pyValue) const; Chris@26: Chris@26: // C++ to Python Chris@26: PyObject *PyValue_From_CValue(const char*) const; Chris@26: PyObject *PyValue_From_CValue(const std::string& x) const { return PyValue_From_CValue(x.c_str()); } Chris@26: PyObject *PyValue_From_CValue(size_t) const; Chris@26: PyObject *PyValue_From_CValue(double) const; Chris@26: PyObject *PyValue_From_CValue(float x) const { return PyValue_From_CValue((double)x); } Chris@26: PyObject *PyValue_From_CValue(bool) const; Chris@26: Chris@26: // Sequence types Chris@26: std::vector PyValue_To_StringVector (PyObject*) const; Chris@26: std::vector PyValue_To_FloatVector (PyObject*) const; Chris@26: std::vector PyList_To_FloatVector (PyObject*) const; Chris@26: Chris@26: PyObject *PyValue_From_StringVector(const std::vector &) const; Chris@26: Chris@26: // Numpy types Chris@26: #ifdef HAVE_NUMPY Chris@26: std::vector PyArray_To_FloatVector (PyObject *pyValue) const; Chris@26: PyObject *FloatVector_To_PyArray(const std::vector &) const; // Copying the data Chris@26: #endif Chris@26: Chris@26: /// Convert DTYPE type 1D NumpyArray to std::vector Chris@26: template Chris@26: std::vector PyArray_Convert(void* raw_data_ptr, long length, size_t strides) const Chris@26: { Chris@26: std::vector rValue; Chris@26: Chris@26: /// check if the array is continuous, if not use strides info Chris@26: if (sizeof(DTYPE)!=strides) { Chris@26: #ifdef _DEBUG_VALUES Chris@26: cerr << "Warning: discontinuous numpy array. Strides: " << strides << " bytes. sizeof(dtype): " << sizeof(DTYPE) << endl; Chris@26: #endif Chris@26: char* data = (char*) raw_data_ptr; Chris@26: for (long i = 0; i PyArray0D_Convert(PyArrayInterface *ai) const Chris@26: { Chris@26: std::vector rValue; Chris@26: if ((ai->typekind) == *"f") Chris@26: rValue.push_back((float)*(double*)(ai->data)); Chris@26: else { Chris@26: setValueError("Unsupported NumPy data type.",m_strict); Chris@26: return rValue; Chris@26: } Chris@26: #ifdef _DEBUG_VALUES Chris@26: cerr << "value: " << rValue[0] << endl; Chris@26: #endif Chris@26: return rValue; Chris@26: } Chris@26: Chris@26: private: Chris@26: bool m_strict; Chris@26: mutable bool m_error; Chris@26: mutable std::queue m_errorQueue; Chris@26: bool m_numpyInstalled; Chris@26: Chris@26: void setValueError(std::string,bool) const; Chris@26: ValueError& lastError() const; Chris@26: Chris@26: public: Chris@26: const bool& error; Chris@26: Chris@26: }; Chris@26: Chris@26: #endif