annotate PyTypeConversions.h @ 26:014c48d6f360

Now we know what we want from Vampy source, bring it in here again and lose the subrepo
author Chris Cannam
date Wed, 26 Nov 2014 09:48:35 +0000
parents
children fb6519598734
rev   line source
Chris@26 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@26 2
Chris@26 3 /*
Chris@26 4 VampyHost
Chris@26 5
Chris@26 6 Use Vamp audio analysis plugins in Python
Chris@26 7
Chris@26 8 Gyorgy Fazekas and Chris Cannam
Chris@26 9 Centre for Digital Music, Queen Mary, University of London
Chris@26 10 Copyright 2008-2014 Queen Mary, University of London
Chris@26 11
Chris@26 12 Permission is hereby granted, free of charge, to any person
Chris@26 13 obtaining a copy of this software and associated documentation
Chris@26 14 files (the "Software"), to deal in the Software without
Chris@26 15 restriction, including without limitation the rights to use, copy,
Chris@26 16 modify, merge, publish, distribute, sublicense, and/or sell copies
Chris@26 17 of the Software, and to permit persons to whom the Software is
Chris@26 18 furnished to do so, subject to the following conditions:
Chris@26 19
Chris@26 20 The above copyright notice and this permission notice shall be
Chris@26 21 included in all copies or substantial portions of the Software.
Chris@26 22
Chris@26 23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@26 24 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@26 25 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Chris@26 26 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
Chris@26 27 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@26 28 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@26 29 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@26 30
Chris@26 31 Except as contained in this notice, the names of the Centre for
Chris@26 32 Digital Music; Queen Mary, University of London; and the authors
Chris@26 33 shall not be used in advertising or otherwise to promote the sale,
Chris@26 34 use or other dealings in this Software without prior written
Chris@26 35 authorization.
Chris@26 36 */
Chris@26 37
Chris@26 38 /*
Chris@26 39 PyTypeConversions: Type safe conversion utilities between Python
Chris@26 40 types and basic C/C++ types.
Chris@26 41 */
Chris@26 42
Chris@26 43 #ifndef PY_TYPE_CONVERSIONS_H
Chris@26 44 #define PY_TYPE_CONVERSIONS_H
Chris@26 45
Chris@26 46 #include <Python.h>
Chris@26 47
Chris@26 48 #ifdef HAVE_NUMPY
Chris@26 49 #define PY_ARRAY_UNIQUE_SYMBOL VAMPY_ARRAY_API
Chris@26 50 #define NO_IMPORT_ARRAY
Chris@26 51 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
Chris@26 52 #include "numpy/arrayobject.h"
Chris@26 53 #endif
Chris@26 54
Chris@26 55 #include <vector>
Chris@26 56 #include <queue>
Chris@26 57 #include <string>
Chris@26 58 #include <sstream>
Chris@26 59 #include <iostream>
Chris@26 60
Chris@26 61 using std::cerr;
Chris@26 62 using std::endl;
Chris@26 63
Chris@26 64 #ifdef HAVE_NUMPY
Chris@26 65 enum eArrayDataType {
Chris@26 66 dtype_float32 = (int) NPY_FLOAT,
Chris@26 67 dtype_complex64 = (int) NPY_CFLOAT
Chris@26 68 };
Chris@26 69 #endif
Chris@26 70
Chris@26 71 /* C++ mapping of PyNone Type */
Chris@26 72 struct NoneType {};
Chris@26 73
Chris@26 74 // Data
Chris@26 75 class ValueError
Chris@26 76 {
Chris@26 77 public:
Chris@26 78 ValueError() {}
Chris@26 79 ValueError(std::string m, bool s) : message(m),strict(s) {}
Chris@26 80 std::string location;
Chris@26 81 std::string message;
Chris@26 82 bool strict;
Chris@26 83 std::string str() const {
Chris@26 84 return (location.empty()) ? message : message + "\nLocation: " + location;}
Chris@26 85 void print() const { cerr << str() << endl; }
Chris@26 86 template<typename V> ValueError &operator<< (const V& v)
Chris@26 87 {
Chris@26 88 std::ostringstream ss;
Chris@26 89 ss << v;
Chris@26 90 location += ss.str();
Chris@26 91 return *this;
Chris@26 92 }
Chris@26 93 };
Chris@26 94
Chris@26 95 class PyTypeConversions
Chris@26 96 {
Chris@26 97 public:
Chris@26 98 PyTypeConversions();
Chris@26 99 ~PyTypeConversions();
Chris@26 100
Chris@26 101 // Utilities
Chris@26 102 void setStrictTypingFlag(bool b) {m_strict = b;}
Chris@26 103 void setNumpyInstalled(bool b) {m_numpyInstalled = b;}
Chris@26 104 ValueError getError() const;
Chris@26 105 std::string PyValue_Get_TypeName(PyObject*) const;
Chris@26 106
Chris@26 107 // Basic type conversion: Python to C++
Chris@26 108 float PyValue_To_Float(PyObject*) const;
Chris@26 109 size_t PyValue_To_Size_t(PyObject*) const;
Chris@26 110 bool PyValue_To_Bool(PyObject*) const;
Chris@26 111 std::string PyValue_To_String(PyObject*) const;
Chris@26 112 long PyValue_To_Long(PyObject*) const;
Chris@26 113 // int PyValue_To_Int(PyObject* pyValue) const;
Chris@26 114
Chris@26 115 // C++ to Python
Chris@26 116 PyObject *PyValue_From_CValue(const char*) const;
Chris@26 117 PyObject *PyValue_From_CValue(const std::string& x) const { return PyValue_From_CValue(x.c_str()); }
Chris@26 118 PyObject *PyValue_From_CValue(size_t) const;
Chris@26 119 PyObject *PyValue_From_CValue(double) const;
Chris@26 120 PyObject *PyValue_From_CValue(float x) const { return PyValue_From_CValue((double)x); }
Chris@26 121 PyObject *PyValue_From_CValue(bool) const;
Chris@26 122
Chris@26 123 // Sequence types
Chris@26 124 std::vector<std::string> PyValue_To_StringVector (PyObject*) const;
Chris@26 125 std::vector<float> PyValue_To_FloatVector (PyObject*) const;
Chris@26 126 std::vector<float> PyList_To_FloatVector (PyObject*) const;
Chris@26 127
Chris@26 128 PyObject *PyValue_From_StringVector(const std::vector<std::string> &) const;
Chris@26 129
Chris@26 130 // Numpy types
Chris@26 131 #ifdef HAVE_NUMPY
Chris@26 132 std::vector<float> PyArray_To_FloatVector (PyObject *pyValue) const;
Chris@26 133 PyObject *FloatVector_To_PyArray(const std::vector<float> &) const; // Copying the data
Chris@26 134 #endif
Chris@26 135
Chris@26 136 /// Convert DTYPE type 1D NumpyArray to std::vector<RET>
Chris@26 137 template<typename RET, typename DTYPE>
Chris@26 138 std::vector<RET> PyArray_Convert(void* raw_data_ptr, long length, size_t strides) const
Chris@26 139 {
Chris@26 140 std::vector<RET> rValue;
Chris@26 141
Chris@26 142 /// check if the array is continuous, if not use strides info
Chris@26 143 if (sizeof(DTYPE)!=strides) {
Chris@26 144 #ifdef _DEBUG_VALUES
Chris@26 145 cerr << "Warning: discontinuous numpy array. Strides: " << strides << " bytes. sizeof(dtype): " << sizeof(DTYPE) << endl;
Chris@26 146 #endif
Chris@26 147 char* data = (char*) raw_data_ptr;
Chris@26 148 for (long i = 0; i<length; ++i){
Chris@26 149 rValue.push_back((RET)(*((DTYPE*)data)));
Chris@26 150 #ifdef _DEBUG_VALUES
Chris@26 151 cerr << "value: " << (RET)(*((DTYPE*)data)) << endl;
Chris@26 152 #endif
Chris@26 153 data+=strides;
Chris@26 154 }
Chris@26 155 return rValue;
Chris@26 156 }
Chris@26 157
Chris@26 158 DTYPE* data = (DTYPE*) raw_data_ptr;
Chris@26 159 for (long i = 0; i<length; ++i){
Chris@26 160 #ifdef _DEBUG_VALUES
Chris@26 161 cerr << "value: " << (RET)data[i] << endl;
Chris@26 162 #endif
Chris@26 163 rValue.push_back((RET)data[i]);
Chris@26 164 }
Chris@26 165 return rValue;
Chris@26 166 }
Chris@26 167
Chris@26 168 /// this is a special case. numpy.float64 has an array conversions but no array descriptor
Chris@26 169 std::vector<float> PyArray0D_Convert(PyArrayInterface *ai) const
Chris@26 170 {
Chris@26 171 std::vector<float> rValue;
Chris@26 172 if ((ai->typekind) == *"f")
Chris@26 173 rValue.push_back((float)*(double*)(ai->data));
Chris@26 174 else {
Chris@26 175 setValueError("Unsupported NumPy data type.",m_strict);
Chris@26 176 return rValue;
Chris@26 177 }
Chris@26 178 #ifdef _DEBUG_VALUES
Chris@26 179 cerr << "value: " << rValue[0] << endl;
Chris@26 180 #endif
Chris@26 181 return rValue;
Chris@26 182 }
Chris@26 183
Chris@26 184 private:
Chris@26 185 bool m_strict;
Chris@26 186 mutable bool m_error;
Chris@26 187 mutable std::queue<ValueError> m_errorQueue;
Chris@26 188 bool m_numpyInstalled;
Chris@26 189
Chris@26 190 void setValueError(std::string,bool) const;
Chris@26 191 ValueError& lastError() const;
Chris@26 192
Chris@26 193 public:
Chris@26 194 const bool& error;
Chris@26 195
Chris@26 196 };
Chris@26 197
Chris@26 198 #endif