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