Mercurial > hg > vampy
comparison PyTypeConversions.h @ 71:40a01bb24209 vampyhost
Pull apart some type conversion classes for possible use in VamPy Host
author | Chris Cannam |
---|---|
date | Thu, 20 Nov 2014 13:02:50 +0000 |
parents | PyTypeInterface.h@5664fe298af2 |
children | ffaa1fb3d7de |
comparison
equal
deleted
inserted
replaced
70:6c755f3e1173 | 71:40a01bb24209 |
---|---|
1 /* -*- c-basic-offset: 8 indent-tabs-mode: t -*- */ | |
2 /* | |
3 | |
4 * Vampy : This plugin is a wrapper around the Vamp plugin API. | |
5 * It allows for writing Vamp plugins in Python. | |
6 | |
7 * Centre for Digital Music, Queen Mary University of London. | |
8 * Copyright (C) 2008-2009 Gyorgy Fazekas, QMUL. (See Vamp sources | |
9 * for licence information.) | |
10 | |
11 */ | |
12 | |
13 /* | |
14 PyTypeConversions: Type safe conversion utilities between Python types | |
15 and basic C/C++ types. | |
16 */ | |
17 | |
18 #ifndef _PY_TYPE_CONVERSIONS_H_ | |
19 #define _PY_TYPE_CONVERSIONS_H_ | |
20 #include <Python.h> | |
21 #ifdef HAVE_NUMPY | |
22 #define PY_ARRAY_UNIQUE_SYMBOL VAMPY_ARRAY_API | |
23 #define NO_IMPORT_ARRAY | |
24 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION | |
25 #include "numpy/arrayobject.h" | |
26 #endif | |
27 | |
28 #include <vector> | |
29 #include <queue> | |
30 #include <string> | |
31 #include <sstream> | |
32 #include <iostream> | |
33 | |
34 using std::cerr; | |
35 using std::endl; | |
36 | |
37 #ifdef HAVE_NUMPY | |
38 enum eArrayDataType { | |
39 dtype_float32 = (int) NPY_FLOAT, | |
40 dtype_complex64 = (int) NPY_CFLOAT | |
41 }; | |
42 #endif | |
43 | |
44 /* C++ mapping of PyNone Type */ | |
45 struct NoneType {}; | |
46 | |
47 // Data | |
48 class ValueError | |
49 { | |
50 public: | |
51 ValueError() {} | |
52 ValueError(std::string m, bool s) : message(m),strict(s) {} | |
53 std::string location; | |
54 std::string message; | |
55 bool strict; | |
56 std::string str() const { | |
57 return (location.empty()) ? message : message + "\nLocation: " + location;} | |
58 void print() const { cerr << str() << endl; } | |
59 template<typename V> ValueError &operator<< (const V& v) | |
60 { | |
61 std::ostringstream ss; | |
62 ss << v; | |
63 location += ss.str(); | |
64 return *this; | |
65 } | |
66 }; | |
67 | |
68 class PyTypeConversions | |
69 { | |
70 public: | |
71 PyTypeConversions(); | |
72 ~PyTypeConversions(); | |
73 | |
74 // Utilities | |
75 void setStrictTypingFlag(bool b) {m_strict = b;} | |
76 void setNumpyInstalled(bool b) {m_numpyInstalled = b;} | |
77 ValueError getError() const; | |
78 std::string PyValue_Get_TypeName(PyObject*) const; | |
79 | |
80 // Basic type conversion: Python to C++ | |
81 float PyValue_To_Float(PyObject*) const; | |
82 size_t PyValue_To_Size_t(PyObject*) const; | |
83 bool PyValue_To_Bool(PyObject*) const; | |
84 std::string PyValue_To_String(PyObject*) const; | |
85 long PyValue_To_Long(PyObject*) const; | |
86 // int PyValue_To_Int(PyObject* pyValue) const; | |
87 | |
88 // C++ to Python | |
89 PyObject *PyValue_From_CValue(const char*) const; | |
90 PyObject *PyValue_From_CValue(const std::string& x) const { return PyValue_From_CValue(x.c_str()); } | |
91 PyObject *PyValue_From_CValue(size_t) const; | |
92 PyObject *PyValue_From_CValue(double) const; | |
93 PyObject *PyValue_From_CValue(float x) const { return PyValue_From_CValue((double)x); } | |
94 PyObject *PyValue_From_CValue(bool) const; | |
95 | |
96 // Sequence types | |
97 std::vector<std::string> PyValue_To_StringVector (PyObject*) const; | |
98 std::vector<float> PyValue_To_FloatVector (PyObject*) const; | |
99 std::vector<float> PyList_To_FloatVector (PyObject*) const; | |
100 | |
101 // Numpy types | |
102 #ifdef HAVE_NUMPY | |
103 std::vector<float> PyArray_To_FloatVector (PyObject *pyValue) const; | |
104 #endif | |
105 | |
106 /// Convert DTYPE type 1D NumpyArray to std::vector<RET> | |
107 template<typename RET, typename DTYPE> | |
108 std::vector<RET> PyArray_Convert(void* raw_data_ptr, long length, size_t strides) const | |
109 { | |
110 std::vector<RET> rValue; | |
111 | |
112 /// check if the array is continuous, if not use strides info | |
113 if (sizeof(DTYPE)!=strides) { | |
114 #ifdef _DEBUG_VALUES | |
115 cerr << "Warning: discontinuous numpy array. Strides: " << strides << " bytes. sizeof(dtype): " << sizeof(DTYPE) << endl; | |
116 #endif | |
117 char* data = (char*) raw_data_ptr; | |
118 for (long i = 0; i<length; ++i){ | |
119 rValue.push_back((RET)(*((DTYPE*)data))); | |
120 #ifdef _DEBUG_VALUES | |
121 cerr << "value: " << (RET)(*((DTYPE*)data)) << endl; | |
122 #endif | |
123 data+=strides; | |
124 } | |
125 return rValue; | |
126 } | |
127 | |
128 DTYPE* data = (DTYPE*) raw_data_ptr; | |
129 for (long i = 0; i<length; ++i){ | |
130 #ifdef _DEBUG_VALUES | |
131 cerr << "value: " << (RET)data[i] << endl; | |
132 #endif | |
133 rValue.push_back((RET)data[i]); | |
134 } | |
135 return rValue; | |
136 } | |
137 | |
138 /// this is a special case. numpy.float64 has an array conversions but no array descriptor | |
139 inline std::vector<float> PyArray0D_Convert(PyArrayInterface *ai) const | |
140 { | |
141 std::vector<float> rValue; | |
142 if ((ai->typekind) == *"f") | |
143 rValue.push_back((float)*(double*)(ai->data)); | |
144 else { | |
145 setValueError("Unsupported NumPy data type.",m_strict); | |
146 return rValue; | |
147 } | |
148 #ifdef _DEBUG_VALUES | |
149 cerr << "value: " << rValue[0] << endl; | |
150 #endif | |
151 return rValue; | |
152 } | |
153 | |
154 private: | |
155 bool m_strict; | |
156 mutable bool m_error; | |
157 mutable std::queue<ValueError> m_errorQueue; | |
158 bool m_numpyInstalled; | |
159 | |
160 void setValueError(std::string,bool) const; | |
161 ValueError& lastError() const; | |
162 | |
163 public: | |
164 const bool& error; | |
165 | |
166 }; | |
167 | |
168 #endif |